-- 使用默认折扣(九折)
SELECT public.discount_price(100.0);
-- 90.0
-- 指定折扣(八折)
SELECT public.discount_price(100.0, 0.8);
-- 80.0
-- 在查询中使用
SELECT order_id, amount, public.discount_price(amount) AS discounted
FROM doc_orders
WHERE category = 'electronics';
order_id
amount
discounted
1
99.9
89.91
4
199.0
179.1
场景二:标量函数 — 封装分类规则
需求:根据金额对订单分级,规则集中维护。
CREATE OR REPLACE FUNCTION public.order_tier(amount DOUBLE)
RETURNS STRING
RETURN CASE
WHEN amount >= 200 THEN 'Premium'
WHEN amount >= 50 THEN 'Standard'
WHEN amount > 0 THEN 'Basic'
ELSE 'Free'
END;
SELECT order_id, amount, public.order_tier(amount) AS tier
FROM doc_orders
ORDER BY amount DESC;
order_id
amount
tier
2
299.0
Premium
4
199.0
Standard
1
99.9
Standard
3
49.5
Basic
5
0.0
Free
场景三:标量函数 — 数据清洗
需求:清洗手机号,去除非数字字符。
CREATE OR REPLACE FUNCTION public.clean_phone(phone STRING)
RETURNS STRING
RETURN REGEXP_REPLACE(TRIM(phone), '[0-9]', '');
CREATE OR REPLACE FUNCTION public.date_range(start_date DATE, end_date DATE)
RETURNS TABLE (dt DATE)
RETURN
SELECT DATE_ADD(start_date, pos) AS dt
FROM (SELECT POSEXPLODE(SPLIT(SPACE(DATEDIFF(end_date, start_date)), ' '))) t(pos, v);
-- 直接调用
SELECT * FROM public.date_range(DATE '2024-01-01', DATE '2024-01-05');
dt
2024-01-01
2024-01-02
2024-01-03
2024-01-04
2024-01-05
-- 与订单表 LEFT JOIN,找出无订单的日期
SELECT d.dt, COALESCE(SUM(o.amount), 0) AS daily_revenue
FROM public.date_range(DATE '2024-01-01', DATE '2024-01-05') d
LEFT JOIN doc_orders o ON o.order_date = d.dt
GROUP BY d.dt
ORDER BY d.dt;
dt
daily_revenue
2024-01-01
99.9
2024-01-02
0
2024-01-03
348.5
2024-01-04
0
2024-01-05
199
函数管理
查看函数定义
DESC FUNCTION public.order_tier;
返回函数名、创建时间、完整 SQL 定义等信息。
更新函数
使用
CREATE OR REPLACE FUNCTION
CREATE OR REPLACE FUNCTION
直接覆盖,无需先删除:
CREATE OR REPLACE FUNCTION public.order_tier(amount DOUBLE)
RETURNS STRING
RETURN CASE
WHEN amount >= 300 THEN 'VIP' -- 新增 VIP 档
WHEN amount >= 200 THEN 'Premium'
WHEN amount >= 50 THEN 'Standard'
WHEN amount > 0 THEN 'Basic'
ELSE 'Free'
END;