跳转到主要内容
模块 6 · 第 4 课(共 4)课程中的24/57~10 min
模块课程(4/4)

CAST 和类型转换

SQL 是强类型的:每列都有一个类型 (INTEGER, TEXT, NUMERIC、DATE、TIMESTAMP…),并且许多操作需要这些类型 匹配。当他们不这样做时 - 或者当你想要格式化一个值时 不同的是——你使用 cast。

两个等效语法

SQL
-- SQL standard:
CAST(123 AS TEXT)

-- PostgreSQL shorthand (più comune nella pratica):
123::text

两种形式是相同的。简写 ::type 更加紧凑, 与其他表达式很好地链接:

SQL
SELECT ordered_at::date AS day,
       (oi.quantity * oi.unit_price)::numeric(10,2) AS total,
       id::text || ' - ' || email AS label
FROM   …;

对数据集的有用转换

SQL
TIMESTAMP → DATE          ordered_at::date
NUMERIC   → INTEGER       price::int           -- tronca!
INTEGER   → NUMERIC       quantity::numeric    -- per evitare div. intera
INTEGER   → TEXT          id::text             -- per concatenare con ||
TEXT      → DATE          '2024-03-05'::date
NUMERIC   → TEXT          price::text          -- per LIKE su numeri

当强制转换可能失败时

SQL
SELECT 'abc'::int;   -- ERRORE: invalid input syntax for type integer
SELECT '12.5'::int;  -- ERRORE: invalid input syntax for type integer
SELECT 12.5::int;    -- 12   (cast numerico-numerico: arrotonda)

从 string → number 或 string → date 进行转换是最危险的: 如果字符串与预期不完全匹配,它们会引发错误 格式。在生产中,对于外部数据,最好先进行验证 与 TRIM / LOWER / 正则表达式。

演员表和排序依据

产生微妙错误的情况:对数字存储为文本进行排序。

SQL
SELECT '2', '10', '1' ORDER BY 1;  -- '1', '10', '2'   (alfabetico!)

解决方案:在ORDER BY内部强制转换:

SQL
SELECT code FROM articles ORDER BY code::int;

尝试一下

锻炼#sql.m6.l4.e1
尝试:0加载中...

对于每个订单,显示 ID 和日期(仅ordered_at 的日期部分,类型为日期)。两列。按 ID 订购。

正在加载编辑器...
显示提示

TIMESTAMP → DATE 转换会删除时间:ordered_at::date。

3 次尝试后可用的解决方案

复习练习

锻炼#sql.m6.l4.e2
尝试:0加载中...

对于每个客户,显示一个标签列,该标签列将 ID 和电子邮件连接起来,并用“-”分隔(例如“1 - alice.rossi@example.com”)。按 ID 订购。

正在加载编辑器...
显示提示

||运算符需要相同类型的操作数:将 id 转换为文本是最简洁的方法。

3 次尝试后可用的解决方案