簡體   English   中英

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

[英]SQL- Use CASE without GROUP BY

如何在SQL不使用CASE表達式而無需GROUP BY CASE下獲取值的總和(或請提出實現此目標的任何其他最佳方法)

查詢

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 |
+-------------+--------+

在lab_date之前與GROUP取得聯系

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

我們如何獲得如下結果

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

我認為您需要條件聚合。 其中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 ;

請注意,SQL Server執行整數除法。 因此,我建議您不要寫5/100,因為這將得出0 即使先執行乘法,也不習慣保留小數點。

為什么要繞開完全為您設計的功能?

嘗試這樣的事情:

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

免責聲明:我這里沒有MS SQL Server,因此如果出現語法錯誤,請對我感到羞恥。

說明:您分別計算X天之前的時間和X天之后的時間的兩個集合。 然后將這兩個集合合並,然后像往常一樣進行分組。

為什么這比大小寫更好? WHERE子句受益於date列上的(可能)索引,但是case語句是針對每一行進行評估的,因此查詢會掃描表中的每一行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM