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

数值函数

PostgreSQL 拥有您所期望的所有数字函数 — 外加一些 键入值得立即了解的陷阱。

最常用的功能

SQL
ROUND(price, 2)     -- arrotonda a 2 decimali (banker's rounding "half to even")
CEIL(price)         -- arrotonda per eccesso (verso +∞)
FLOOR(price)        -- arrotonda per difetto (verso −∞)
ABS(-5)             -- 5  (valore assoluto)
MOD(10, 3)          -- 1  (resto della divisione)  — anche 10 % 3
POWER(2, 10)        -- 1024
SQRT(16)            -- 4

仅当 number 为 NUMERIC (不是 DOUBLE PRECISION)。在我们的数据集中 products.price 是 NUMERIC(10,2), 所以我们已经准备好了。

整数除法与小数除法

经典的陷阱:

SQL
SELECT 1 / 2;          -- 0  (entrambi interi → divisione intera!)
SELECT 1.0 / 2;        -- 0.5
SELECT 1::numeric / 2; -- 0.50000000000000000000

当您划分两个 INTEGER 列时,您会得到一个 INTEGER。为了避免 截断,将其中之一转换为 NUMERIC 或乘以 1.0:

SQL
-- Sbagliato: percentuale sempre 0 finché numeratore < denominatore
SELECT shipped / total FROM …;

-- Corretto:
SELECT shipped::numeric / total FROM …;
SELECT ROUND(shipped * 100.0 / total, 2) AS percentage FROM …;

数据集上的示例

SQL
-- Prezzo scontato del 10%, arrotondato a 2 decimali:
SELECT name,
       price,
       ROUND(price * 0.9, 2) AS discounted_price
FROM   products
ORDER BY id;

-- Prezzo "psicologico" sempre arrotondato per eccesso al multiplo di 1:
SELECT name, CEIL(price) AS rounded_price
FROM   products
WHERE  price < 100
ORDER BY price;

尝试一下

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

对于每个产品,显示名称、价格(原价)和折扣价(价格减少 10%,四舍五入到小数点后两位)。按 ID 订购。

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

通过乘以 0.9 将价格降低 10%,然后使用 ROUND(..., 2) 舍入。

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

复习练习

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

对于每个已交付订单(状态=“已交付”),将 id 和 wait_days 显示为ordered_at 和shipping_at 之间的整数天数(向下舍入)。按 wait_days 降序排列,然后按 id 排列。

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

shipped_at - ordered_at returns an INTERVAL; EXTRACT(EPOCH FROM …) turns it into seconds; divide by 86400 (seconds in a day) and take the FLOOR.

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