简体   繁体   English

为每一列添加总计的行

[英]Add a row with totals for each column

I am trying to add a row to a SQL select query that contains a sum (or any other operation, such as an average, for that matter) as a last row. 我正在尝试向SQL选择查询添加一行,该查询包含一个总和(或其他任何操作,例如平均值)作为最后一行。 In this it is something similar to GROUP BY ... WITH ROLLUP. 在此类似于“ GROUP BY ... WITH ROLLUP”。

To begin with: let's say I have a table t with fields ID, A, B and C, all of which are numbers. 首先,假设我有一个表t,其中包含字段ID,A,B和C,它们都是数字。 Also, ID is not unique, but rather a category. 另外,ID不是唯一的,而是一个类别。 My SELECT query is supposed to count how many of these numbers fall within a designated range. 我的SELECT查询应该计算出这些数字中有多少属于指定范围内。

So, for example, the end result would be 因此,例如,最终结果将是

(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) );

However, this solution is not ideal, for I need to re-state the conditions for A,B and C. I would like to know whether there is a simple way of accomplishing the same result specifying the conditions only once. 但是,此解决方案并不理想,因为我需要重新声明A,B和C的条件。我想知道是否有一种简单的方法可以仅指定一次条件来完成相同的结果。

Thanks in advance. 提前致谢。

I don't think there's a simpler solution. 我认为没有比这更简单的解决方案了。 But I would rewrite your queries like this: 但我会这样重写您的查询:

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

Well, without the average you can do: 好吧,没有平均水平,您可以做:

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

Which I would write as: 我将其写为:

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

I'm not sure how rollup works with avg, so the final version is: 我不确定汇总如何与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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM