如何利用SQL UNION从三个查询取最大值?存储过程最佳实践咨询
从三个字段中选取最大值的SQL最佳实践方案分析
需求:编写SQL存储过程,从demand、average、forecast三个值中选取最大值,已获取这三个值的查询语句,咨询以下两个方案的最佳实践:
方案分析
方案1:临时表+CASE WHEN(可行但繁琐)
该方案通过将三个表的数据分别存入临时表,再关联后用CASE WHEN逐行比较取最大值,逻辑正确但流程冗余,代码如下:
SELECT Plant, Material, Dmd INTO #T1 FROM Table1 SELECT Plant, Material, Avg INTO #T2 FROM Table2 SELECT Plant, Material, Fcst INTO #T3 FROM Table3 SELECT a.Plant, a.Material, CASE WHEN Dmd > Avg AND Dmd > Fcst THEN Dmd ELSE CASE WHEN Avg > Fcst THEN Avg ELSE Fcst END END as 'Output' FROM #T1 a INNER JOIN #T2 b on a.Plant = b.Plant AND a.Material = b.Material INNER JOIN #T3 c on a.Plant = c.Plant AND a.Material = c.Material
方案2:UNION合并查询(不可行)
该方案逻辑错误,无法实现需求。UNION的作用是将多个结果集纵向合并,而非横向关联三个表的字段。执行该SQL时,子查询a、b、c通过UNION合并后,每行仅包含Plant、Material和单个字段值(Dmd/Avg/Fcst),无法在CASE语句中同时获取三个值进行比较,会导致语法错误或结果不符合预期,代码如下:
SELECT a.Plant, a.Material, CASE WHEN Dmd > Avg AND Dmd > Fcst THEN Dmd ELSE CASE WHEN Avg > Fcst THEN Avg ELSE Fcst END END as 'Output' FROM (SELECT Plant, Material, Dmd FROM Table1) a UNION (SELECT Plant, Material, Avg FROM Table2) b UNION (SELECT Plant, Material, Fcst FROM Table3) c
最佳实践写法
无需使用临时表,直接关联三个表,通过CASE WHEN或行构造器结合MAX函数实现,更高效简洁:
写法1:直接关联+CASE WHEN
SELECT t1.Plant, t1.Material, CASE WHEN t1.Dmd >= t2.Avg AND t1.Dmd >= t3.Fcst THEN t1.Dmd WHEN t2.Avg >= t3.Fcst THEN t2.Avg ELSE t3.Fcst END AS Output FROM Table1 t1 INNER JOIN Table2 t2 ON t1.Plant = t2.Plant AND t1.Material = t2.Material INNER JOIN Table3 t3 ON t1.Plant = t3.Plant AND t1.Material = t3.Material
写法2:行构造器+MAX函数(更简洁)
通过VALUES构造包含三个值的临时行集,再取最大值,适合字段较多的场景:
SELECT t1.Plant, t1.Material, (SELECT MAX(val) FROM (VALUES (t1.Dmd), (t2.Avg), (t3.Fcst)) AS vals(val)) AS Output FROM Table1 t1 INNER JOIN Table2 t2 ON t1.Plant = t2.Plant AND t1.Material = t2.Material INNER JOIN Table3 t3 ON t1.Plant = t3.Plant AND t1.Material = t3.Material
补充说明
根据业务场景,三个表的Plant和Material一一对应,因此使用INNER JOIN即可;若存在不匹配的情况,可改用LEFT JOIN并通过ISNULL函数处理NULL值(如ISNULL(t1.Dmd, 0))。
示例数据验证:
- Table1:
1000 x 3 - Table2:
1000 x 6 - Table3:
1000 x 4.5
执行上述最佳写法后,输出结果符合预期:
1000 x 6
内容的提问来源于stack exchange,提问作者Katelyn Clasper
相关产品推荐
相关产品推荐

