我正在尝试向SQL select查询添加一行,该查询包含一个总和(或任何其他操作,例如平均值)作为最后一行。在这里它类似于GROUP BY ... WITH ROLLUP。
首先:假设我有一个包含字段ID,A,B和C的表t,所有这些都是数字。此外,ID不是唯一的,而是一个类别。我的SELECT查询应该计算这些数字中有多少落在指定范围内。
因此,例如,最终结果将是
(SELECT t.ID, a.ac, b.bc, c.cc FROM t
LEFT JOIN (SELECT COUNT(*) cc,ID FROM t WHERE A BETWEEN 2 AND 4 GROUP BY ID) AS a ON a.ID=t.ID
LEFT JOIN (SELECT AVG(B) cc,ID FROM t WHERE B BETWEEN 19 AND 40 GROUP BY ID) AS b ON b.ID=t.ID
LEFT JOIN (SELECT COUNT(*) cc,ID FROM t WHERE C BETWEEN 12 AND 14 GROUP BY ID) AS c ON a.ID=t.ID GROUP BY t.ID)
union
(select 'Overall',
(SELECT COUNT(*) cc FROM t WHERE A BETWEEN 2 AND 4),
(SELECT AVG(B) cc FROM t WHERE B BETWEEN 19 AND 40),
(SELECT COUNT(*) cc FROM t WHERE C BETWEEN 12 AND 14) );
然而,这个解决方案并不理想,因为我需要重新说明A,B和C的条件。我想知道是否有一种简单的方法来完成相同的结果,只指定条件一次。< / p>
提前致谢。
答案 0 :(得分:2)
我认为没有更简单的解决方案。但我会像这样重写你的查询:
SELECT
t.ID,
count(case when A between 2 and 4 then ID end),
AVG(case when B between 19 and 40 then B end),
COUNT(case when C between 12 and 14 then id end)
FROM t
GROUP BY ID
UNION
select
'Overall',
count(case when A between 2 and 4 then ID end),
AVG(case when B between 19 and 40 then B end),
COUNT(case when C between 12 and 14 then id end)
FROM t
答案 1 :(得分:2)
嗯,如果没有平均值,你可以这样做:
SELECT t.ID,
count(case when A between 2 and 4 then ID end),
AVG(case when B between 19 and 40 then B end),
COUNT(case when C between 12 and 14 then id end)
FROM t
GROUP BY ID with rollup
我会写作:
SELECT t.ID,
sum(case when A between 2 and 4 then 1 else 0 end),
sum(case when B between 19 and 40 then B end)/sum((case when B between 19 and 40 then B end),
sum(case when C between 12 and 14 then 1 else end)
FROM t
GROUP BY ID with rollup
我不确定汇总是如何与avg一起使用的,所以最终版本是:
select coalesce(t.ID, 'Overall'), Acnt,
(case when Bcnt > 0 then Bsum/Bcnt end),
Ccnt
from (select t.ID,
sum(case when A between 2 and 4 then 1 else 0 end) as Acnt,
sum(case when B between 19 and 40 then B end) as Bsum,
sum(case when B between 19 and 40 then B end) as Bcnt,
sum(case when C between 12 and 14 then 1 else end) as Ccnt
FROM t
GROUP BY ID with rollup
) t