Sql-Server

從多個 CASE 語句中減去

  • August 26, 2016

我正在嘗試從 SQL Server 2008 中的以下查詢中獲取淨銷售額。

我們將銷售辨識為類型 1,將信用辨識為類型 8​​。

我想做的是獲得銷售額總和並減去信用總和以獲得 NetSales,但我沒有任何運氣。

我不確定是否應該使用 CASE 語句來獲取 NetSales。我想從查詢中看到以下內容,甚至只顯示 NetSales:

想要的結果

這是查詢:

SELECT TOP (100) PERCENT IM.IM_PROD_CODE, IV.IV_CUKEY, IM.IM_KEY, IM.IM_DESCR,
  SUM(CASE WHEN IV.IV_TYPE = '1' THEN SH.SH_QTY * SH.SH_PRICE END) AS Sales,
SUM(CASE WHEN IV.IV_TYPE = '8' THEN SH.SH_QTY * PK1.SH.SH_PRICE END) AS Credits

FROM IV INNER JOIN
 SH ON IV_ENTITY_ID = SH.SH_IVENTITY_ID AND IV.IV_NUMBER = SH.SH_IVNUMBER INNER JOIN
  IM ON SH.SH_ITEM = IM.IM_KEY
WHERE 
  (IV.IV_TYPE = 1 OR IV.IV_TYPE = 8) AND (IM.IM_PROD_CODE = 'ESY') AND   (SH.SH_DATE >= CONVERT(DATETIME, '2015-11-01 00:00:00', 102))

GROUP BY 
  IV.IV_CUKEY, IM.IM_PROD_CODE, IM.IM_KEY, IM.IM_DESCR, IV.IV_TYPE
HAVING  
  (IM.IM_KEY = 'A-05.000.007.01_LM')

因此,您希望從第一個 SUM 中減去第二個 SUM 的結果。一種選擇是這樣做:

SELECT TOP (100) PERCENT
 IM.IM_PROD_CODE,
 IV.IV_CUKEY,
 IM.IM_KEY,
 IM.IM_DESCR,
 Sales    = SUM(CASE WHEN IV.IV_TYPE = '1' THEN SH.SH_QTY * SH.SH_PRICE END),
 Credits  = SUM(CASE WHEN IV.IV_TYPE = '8' THEN SH.SH_QTY * PK1.SH.SH_PRICE END),
 **NetSales = SUM(CASE WHEN IV.IV_TYPE = '1' THEN SH.SH_QTY * SH.SH_PRICE END)
- SUM(CASE WHEN IV.IV_TYPE = '8' THEN SH.SH_QTY * PK1.SH.SH_PRICE END)**
FROM
 … /* the rest of your query */

是的,您在重複 SUM 表達式,但這很好,只有其中兩個。適用於許多其他語言的DRY原則在 SQL 中的相關性較低,在 SQL 中,重複程式碼可能是實現更好性能的一種完全正常的方式。

但是,在這種情況下,可以通過使用派生表來避免重複:

SELECT
 IM_PROD_CODE,
 IV_CUKEY,
 IM_KEY,
 IM_DESCR,
 Sales,
 Credits,
 NetSales = Sales - Credits
FROM
 (
   … /* the entirety of your current query */
 ) AS derived;

如果可以的話,我還想建議您在指定常量文字的方式上保持一致。我的意思是有時在您的查詢中,您提供匹配的值IV.IV_TYPE作為字元串 ( IV.IV_TYPE = '1') 和其他時間作為數字 ( IV.IV_TYPE = 1)。您應該真正選擇一種方式,當然,它應該是與列的實際類型匹配的方式。

此外,TOP (100) PERCENT您的查詢中的 沒有什麼意義。看起來它可能是中間物化的舊技術的殘餘,但是,它可能不再適用於您的 SQL Server 版本。

您的查詢 ( ) 中還有這個 HAVING 過濾器,HAVING (IM.IM_KEY = 'A-05.000.007.01_LM')如果您將條件移到 WHERE 子句,它會更有效地工作。

最後一點涉及您的第二個 CASE 表達式(第 8 類表達式)。它所引用的列之一使用在 FROM 子句中找不到的別名進行限定:PK1.SH.SH_PRICE。我假設在此處發布您的腳本是某種複制粘貼錯誤,但我想我會讓您知道,以便您更正它。

引用自:https://dba.stackexchange.com/questions/147943