SQL存储过程需求:基于计算列添加IF逻辑实现客户等级划分
解决方法:使用
CASE表达式添加客户等级列 嘿,看起来你只差最后一步啦!要根据总营收OMZET划分等级,最直接也最高效的方式是用SQL的CASE条件表达式——完全不需要子查询或者自定义函数,咱们直接把逻辑嵌入到你的查询里就行。
首先先纠正你存储过程里的一个小语法问题:DECLARE语句应该放在AS关键字之后,不然会触发语法错误。接下来咱们把等级列加进去:
CREATE PROCEDURE sp_klantOverzicht AS DECLARE @beginDatum DATETIME DECLARE @eindDatum DATETIME SET @beginDatum = '2013-01-01 00:00:00.000'; SET @eindDatum = '2017-01-01 00:00:00.000'; SELECT KLANT_NR, SUM(PRIJS) AS OMZET, -- 这里添加等级判断逻辑 CASE WHEN SUM(PRIJS) > 150 THEN 'Gold' WHEN SUM(PRIJS) BETWEEN 100 AND 150 THEN 'Silver' WHEN SUM(PRIJS) BETWEEN 50 AND 99.99 THEN 'Bronze' -- 可根据需求自定义低于50的情况,比如设为'None'或留空 ELSE 'None' END AS KLANT_NIVEAU FROM ( SELECT kl.KLANT_NR, SUM(DATEDIFF(d, h.STARTDATUM, h.EINDDATUM)*a.PRIJS_PER_D) AS PRIJS FROM HUUROVEREENKOMST AS h LEFT JOIN ARTIKEL AS a ON h.BARCODE = a.BARCODE LEFT JOIN KLANT AS kl ON kl.KLANT_NR = h.KLANT_NR WHERE DATEPART(year, h.STARTDATUM) BETWEEN DATEPART(year, @beginDatum) AND DATEPART(year, @eindDatum) GROUP BY kl.KLANT_NR UNION SELECT kl.KLANT_NR, SUM(a.PRIJS) AS PRIJS FROM ARTIKEL AS a LEFT JOIN KOOPOVEREENKOMST AS k ON k.BARCODE = a.BARCODE LEFT JOIN KLANT AS kl ON kl.KLANT_NR = k.KLANT_NR WHERE DATEPART(year, k.DATUM) BETWEEN DATEPART(year, @beginDatum) AND DATEPART(year, @eindDatum) GROUP BY kl.KLANT_NR ) AS overzicht GROUP BY KLANT_NR ORDER BY OMZET DESC
关键说明:
CASE表达式逻辑:- 按从高到低的阈值顺序判断,避免逻辑冲突
- 边界值可灵活调整:比如若你需要
Silver是100≤OMZET<150,只需把对应条件改成WHEN SUM(PRIJS) >=100 AND SUM(PRIJS) <150即可
语法修正:
原代码中DECLARE放在AS之前不符合SQL存储过程规范,必须将变量声明放在AS之后的代码块内。可选性能优化:
子查询用了UNION(自动去重),如果确定两个子查询不会返回相同的KLANT_NR+PRIJS组合,换成UNION ALL可以提升查询效率,省去去重的额外开销。
这样修改后,存储过程就能返回你需要的三列:客户编号、总营收、等级啦!
内容的提问来源于stack exchange,提问作者Bas Pauw
相关产品推荐
相关产品推荐

