简体   繁体   English

SQL-不使用GROUP BY的情况下使用CASE

[英]SQL- Use CASE without GROUP BY

How to get the sum of the value without GROUP BY using CASE expression in SQL (or please suggest any other best way to achieve this) 如何在SQL不使用CASE表达式而无需GROUP BY CASE下获取值的总和(或请提出实现此目标的任何其他最佳方法)

Query : 查询

SELECT 
    CASE
        WHEN [lab_date] <= '2018-03-24'
             AND [lab_date] >= '2018-01-01'
        THEN(ISNULL(SUM(ISNULL([cost], 0) * 5 / 100), 0))
        WHEN [lab_date] >= '2018-03-25'
        THEN(ISNULL((SUM(ISNULL([cost], 0))) - (SUM(ISNULL([cost], 0) * 5 / 100)), 0))
    END AS [tax]
FROM [LABOR];

+-------------+--------+
|  lab_date   |  cost  |
+-------------+--------+
| 2018-03-12  |  75.00 |
| 2018-03-01  | 150.00 |
| 2018-03-11  | 450.00 |
| 2018-03-13  |  37.50 |
| 2018-03-15  | 150.00 |
+-------------+--------+

Getting this with GROUP by lab_date 在lab_date之前与GROUP取得联系

+-------+
|  tax  |
+-------+
| 15.00 |
| 22.50 |
|  3.75 |
|  1.88 |
+-------+

How we can get the result like below 我们如何获得如下结果

+-------+
|  tax  |
+-------+
| 43.13 |
+-------+

I think you want conditional aggregation . 我认为您需要条件聚合。 . . where the case is the argument to SUM() : 其中caseSUM()的参数:

SELECT SUM(CASE WHEN lab_date <= '2018-03-24' AND lab_date >= '2018-01-01' THEN cost * 5.0/100
                WHEN lab_date >= '2018-03-25' THEN cost - cost * 5.0/100
                ELSE 0
           END)  as tax         
FROM LABOR ;

Note that SQL Server does integer division. 请注意,SQL Server执行整数除法。 So I don't recommend ever writing 5/100, because that will evaluate to 0 . 因此,我建议您不要写5/100,因为这将得出0 Even if the multiplication is performed first, not including the decimal point is a bad habit. 即使先执行乘法,也不习惯保留小数点。

Why circumvent the very feature that is exactly designed for your purpose? 为什么要绕开完全为您设计的功能?

Try something like this: 尝试这样的事情:

with
taxes_before(lab_date, tax) as (
  select lab_date, cost*0.05
  from labor
  where lab_date between '2018-01-01' and '2018-03-24'
),
taxes_after(lab_date, tax) as (
  select lab_date, cost*0.95
  from labor
  where lab_date >= '2018-01-25'
),
taxes_all(lab_date, tax) as (
  select lab_date, tax from taxes_before
  union select lab_date, tax from taxes_after
)
select sum(tax)
from taxes_all

Disclaimer: I don't have a MS SQL Server here, so shame on me if there is a syntax error. 免责声明:我这里没有MS SQL Server,因此如果出现语法错误,请对我感到羞耻。

Explanation: You compute the two sets for the time before day X and the time after day X separately. 说明:您分别计算X天之前的时间和X天之后的时间的两个集合。 Then you union those two sets and just group as usual. 然后将这两个集合合并,然后像往常一样进行分组。

Why is this better than the case expression? 为什么这比大小写更好? The WHERE clause benefits from a (possible) index on your date column, but the case statement is evaluated for each row and hence your query scans over every row in your table. WHERE子句受益于date列上的(可能)索引,但是case语句是针对每一行进行评估的,因此查询会扫描表中的每一行。

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

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