通过分组获得条件总和

时间:2012-06-28 16:00:50

标签: sql sql-server sql-server-2008

我的查询返回如下所示的数据:

+------+------+------+------+------+------+------+-------+------+------+------+------+-----+
| Jan  | Feb  | Mar  | Apr  | May  | Jun  | Jul  |  Aug  | Sep  | Oct  | Nov  | Dec  | bla |
+------+------+------+------+------+------+------+-------+------+------+------+------+-----+
|    0 |    0 |    0 |    0 |    0 |    0 |    0 |     0 |    0 |    0 |    2 |    0 |  13 |
|    1 |    0 |    0 |    0 |    0 |    0 |    0 |     0 |    0 |    2 |    0 |    0 |  14 |
|    0 |    0 |    0 |    0 |    0 |    9 |    0 |     0 |    0 |    0 |    8 |   37 |  29 |
|    0 |    0 |    0 |    0 |    0 |    0 |    0 |     0 |    0 |    1 |    0 |  374 |  30 |
|    0 |    0 |    1 |    0 |   78 |    2 |    4 |     8 |   57 |  169 |  116 |  602 |  31 |
|  156 |  255 |   79 |   75 |  684 |  325 |  289 |   194 |  407 |  171 |  584 |  443 |  32 |
| 1561 | 2852 | 2056 |  796 | 2004 | 1755 |  879 |  1052 | 1490 | 1683 | 2532 | 2381 |  33 |
| 4167 | 3841 | 4798 | 3399 | 4132 | 5849 | 3157 |  4381 | 4424 | 4487 | 4178 | 5343 |  34 |
| 5472 | 5939 | 5768 | 4150 | 7483 | 6836 | 6346 |  6288 | 6850 | 7155 | 5706 | 5231 |  35 |
| 5749 | 4741 | 5264 | 4045 | 6544 | 7405 | 7524 |  6625 | 6344 | 5508 | 6513 | 3854 |  36 |
| 5464 | 6323 | 7074 | 4861 | 7244 | 6768 | 6632 |  7389 | 8077 | 8745 | 6738 | 5039 |  37 |
| 5731 | 7205 | 7476 | 5734 | 9103 | 9244 | 7339 |  8970 | 9726 | 9089 | 6328 | 5512 |  38 |
| 7262 | 6149 | 8231 | 6654 | 9886 | 9834 | 9306 | 10065 | 9983 | 9984 | 6738 | 5806 |  39 |
| 5886 | 6934 | 7137 | 6978 | 9034 | 9155 | 7389 |  9437 | 9711 | 8665 | 6593 | 5337 |  40 |
| 5680 | 5167 | 5385 | 5434 | 5548 | 6587 | 8688 |  8246 | 9372 | 7723 | 5805 | 7123 |  41 |
| 3752 | 3550 | 5425 | 4902 | 3153 | 4499 | 4420 |  4575 | 5892 | 6553 | 4927 | 6245 |  42 |
| 2829 | 5561 | 4881 | 4919 | 3779 | 2781 | 3503 |  3898 | 4090 | 4268 | 3946 | 5864 |  43 |
+------+------+------+------+------+------+------+-------+------+------+------+------+-----+

当BLA(最后一个字段)大于40时,我希望它只是对所有值求和并打印41作为最后一行:

+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-----+
|  Jan  |  Feb  |  Mar  |  Apr  |  May  |  Jun  |  Jul  |  Aug  |  Sep  |  Oct  |  Nov  |  Dec  | bla |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-----+
|     0 |     0 |     0 |     0 |     0 |     0 |     0 |     0 |     0 |     0 |     2 |     0 |  13 |
|     1 |     0 |     0 |     0 |     0 |     0 |     0 |     0 |     0 |     2 |     0 |     0 |  14 |
|     0 |     0 |     0 |     0 |     0 |     9 |     0 |     0 |     0 |     0 |     8 |    37 |  29 |
|     0 |     0 |     0 |     0 |     0 |     0 |     0 |     0 |     0 |     1 |     0 |   374 |  30 |
|     0 |     0 |     1 |     0 |    78 |     2 |     4 |     8 |    57 |   169 |   116 |   602 |  31 |
|   156 |   255 |    79 |    75 |   684 |   325 |   289 |   194 |   407 |   171 |   584 |   443 |  32 |
|  1561 |  2852 |  2056 |   796 |  2004 |  1755 |   879 |  1052 |  1490 |  1683 |  2532 |  2381 |  33 |
|  4167 |  3841 |  4798 |  3399 |  4132 |  5849 |  3157 |  4381 |  4424 |  4487 |  4178 |  5343 |  34 |
|  5472 |  5939 |  5768 |  4150 |  7483 |  6836 |  6346 |  6288 |  6850 |  7155 |  5706 |  5231 |  35 |
|  5749 |  4741 |  5264 |  4045 |  6544 |  7405 |  7524 |  6625 |  6344 |  5508 |  6513 |  3854 |  36 |
|  5464 |  6323 |  7074 |  4861 |  7244 |  6768 |  6632 |  7389 |  8077 |  8745 |  6738 |  5039 |  37 |
|  5731 |  7205 |  7476 |  5734 |  9103 |  9244 |  7339 |  8970 |  9726 |  9089 |  6328 |  5512 |  38 |
|  7262 |  6149 |  8231 |  6654 |  9886 |  9834 |  9306 | 10065 |  9983 |  9984 |  6738 |  5806 |  39 |
|  5886 |  6934 |  7137 |  6978 |  9034 |  9155 |  7389 |  9437 |  9711 |  8665 |  6593 |  5337 |  40 |
| 12261 | 14278 | 15691 | 15255 | 12480 | 13867 | 16611 | 16719 | 19354 | 18544 | 14678 | 19232 |  41 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-----+

你可以看到最后一行是所有41和更高的总和。

这是我的疑问:

select 
sum(case when datepart(month,[datetime entered]) = 1 then 1 end) as Jan,
sum(case when datepart(month,[datetime entered]) = 2 then 1 end) as Feb,
sum(case when datepart(month,[datetime entered]) = 3 then 1 end) as Mar,
sum(case when datepart(month,[datetime entered]) = 4 then 1 end) as Apr,
sum(case when datepart(month,[datetime entered]) = 5 then 1 end) as May,
sum(case when datepart(month,[datetime entered]) = 6 then 1 end) as Jun,
sum(case when datepart(month,[datetime entered]) = 7 then 1 end) as Jul,
sum(case when datepart(month,[datetime entered]) = 8 then 1 end) as Aug,
sum(case when datepart(month,[datetime entered]) = 9 then 1 end) as Sep,
sum(case when datepart(month,[datetime entered]) = 10 then 1 end) as Oct,
sum(case when datepart(month,[datetime entered]) = 11 then 1 end) as Nov,
sum(case when datepart(month,[datetime entered]) = 12 then 1 end) as Dec,
DATEPART(yyyy,[datetime entered]) as [Year],
 bla= CASE WHEN datediff(d, CAST([datetime entered] as DATE), CAST([datetime completed] as DATE))*24 + 
 CONVERT(CHAR(2),[datetime completed],108)
 >41 THEN 41 ELSE datediff(d, CAST([datetime entered] as DATE), CAST([datetime completed] as DATE))*24 + 
 CONVERT(CHAR(2),[datetime completed],108)  END


from [TurnAround]

where DATEPART(yyyy,[datetime entered])=2011

group by 

datediff(d, CAST([datetime entered] as DATE), CAST([datetime completed] as DATE))*24 + 
 CONVERT(CHAR(2),[datetime completed],108),

 DATEPART(yyyy,[datetime entered])

 order by bla

如何获得结果,如第二个示例所示,将41之后的所有内容相加?

非常感谢您的指导和帮助!!

2 个答案:

答案 0 :(得分:3)

我建议你考虑考虑这个条件来计算BLA。但是,另一种方法是将当前查询用作派生表并使用CASE

SELECT  SUM(Jan) Jan,
        SUM(Feb) Feb,
        SUM(Mar) Mar,
        SUM(Apr) Apr,
        SUM(May) May,
        SUM(Jun) Jun,
        SUM(Jul) Jul,
        SUM(Aug) Aug,
        SUM(Sep) Sep,
        SUM(Oct) Oct,
        SUM(Nov) Nov,
        SUM(Dec) Dec,
        CASE WHEN Bla >= 41 THEN 41 ELSE Bla END Bla
FROM (Your current query here) DT
GROUP BY CASE WHEN Bla >= 41 THEN 41 ELSE Bla END;

或CTE:

;WITH CTE AS 
(
    Your current query here
)
SELECT  SUM(Jan) Jan,
        SUM(Feb) Feb,
        SUM(Mar) Mar,
        SUM(Apr) Apr,
        SUM(May) May,
        SUM(Jun) Jun,
        SUM(Jul) Jul,
        SUM(Aug) Aug,
        SUM(Sep) Sep,
        SUM(Oct) Oct,
        SUM(Nov) Nov,
        SUM(Dec) Dec,
        CASE WHEN Bla >= 41 THEN 41 ELSE Bla END Bla
FROM CTE
GROUP BY CASE WHEN Bla >= 41 THEN 41 ELSE Bla END;

答案 1 :(得分:1)

我会使用一个公用表表达式,如下所示,虽然我不完全确定bla代表什么;我假设从进入到完成的小时数:

WITH cte AS (SELECT 
    CASE WHEN DATEPART(MONTH, [datetime entered]) = 1 THEN 1 ELSE 0 END AS Jan,
    CASE WHEN DATEPART(MONTH, [datetime entered]) = 2 THEN 1 ELSE 0 END AS Feb,
    CASE WHEN DATEPART(MONTH, [datetime entered]) = 3 THEN 1 ELSE 0 END AS Mar,
    CASE WHEN DATEPART(MONTH, [datetime entered]) = 4 THEN 1 ELSE 0 END AS Apr,
    CASE WHEN DATEPART(MONTH, [datetime entered]) = 5 THEN 1 ELSE 0 END AS May,
    CASE WHEN DATEPART(MONTH, [datetime entered]) = 6 THEN 1 ELSE 0 END AS Jun,
    CASE WHEN DATEPART(MONTH, [datetime entered]) = 7 THEN 1 ELSE 0 END AS Jul,
    CASE WHEN DATEPART(MONTH, [datetime entered]) = 8 THEN 1 ELSE 0 END AS Aug,
    CASE WHEN DATEPART(MONTH, [datetime entered]) = 9 THEN 1 ELSE 0 END AS Sep,
    CASE WHEN DATEPART(MONTH, [datetime entered]) = 10 THEN 1 ELSE 0 END AS Oct,
    CASE WHEN DATEPART(MONTH, [datetime entered]) = 11 THEN 1 ELSE 0 END AS Nov,
    CASE WHEN DATEPART(MONTH, [datetime entered]) = 12 THEN 1 ELSE 0 END AS Dec,
    DATEPART(yyyy, [datetime entered]) AS [Year],
    FLOOR(CAST([datetime completed] AS FLOAT) - CAST([datetime entered] AS FLOAT) * 24) AS bla
)
SELECT SUM(Jan) AS Jan, SUM(Feb) AS Feb, SUM(Mar) AS Mar, SUM(Apr) AS Apr, SUM(May) AS May, SUM(Jun) AS Jun, 
    SUM(Jul) AS Jul, SUM(Aug) AS Aug, SUM(Sep) AS Sep, SUM(Oct) AS Oct, SUM(Nov) AS Nov, SUM(Dec) AS Dec,
    CASE WHEN bla > 41 THEN 41 ELSE bla END AS bla
FROM cte
GROUP BY CASE WHEN bla > 41 THEN 41 ELSE bla END AS bla
ORDER BY CASE WHEN bla > 41 THEN 41 ELSE bla END AS bla