2017-01-10 46 views
1

CASE語句我認爲這將是更容易先顯示一個例子,然後解釋:與條件

SELECT P.ID, 
(CASE WHEN PC.NewCostPrice IS NULL 
THEN P.Cost ELSE MAX(PC.Date) PC.NewCostPrice 
END) 
FROM price AS P 
LEFT OUTER JOIN priceChange as PC 
ON P.ID = PC.ID 

因此在本例中,如果NewCostPrice爲空,即沒有一個價格變化,則我想要正常成本(P.Cost)。但是,如果價格發生變化,我想要最近的(MAX(日期))價格變化。我不確定如何將其納入CASE聲明中。

我覺得可以用子查詢和子句來完成,但是當我嘗試時,這並沒有真正解決。有什麼建議麼?

謝謝!

+0

是'ID'主鍵? – ydoow

回答

2

簡單的方法

SELECT distinct P.ID, 
    ISNULL((SELECT TOP 1 PC1.NewCostPrice FROM priceChange as PC1 WHERE PC1.ID = p.id ORDER BY PC1.Date DESC), p.cost) 
    FROM price AS P 
-1
SELECT P.ID 
      ,(CASE 
       WHEN PC.NewCostPrice IS NULL 
        THEN P.Cost 
       ELSE (SELECT TOP 1 PC1.NewCostPrice 
         FROM priceChange PC1 
         WHERE PC1.ID = PC.ID 
         GROUP BY PC1.NewCostPrice, PC1.Date 
ORDER BY PC1.Date DESC 
        ) 
       END 
      ) 
    FROM price AS P 
    LEFT OUTER JOIN priceChange as PC 
    ON P.ID = PC.ID 
+0

感謝Sam的快速反應!然而,這並沒有真正解決,它選擇了錯誤的價值觀......我必須研究爲什麼,也許是我猜測的錯誤日期。我還必須在子查詢中添加'SELECT TOP 1',並且HAVING子句需要一個條件,所以我添加了'HAVING PC1.Date = MAX(PC1.Date)' – Austin

+0

對不起。現在檢查更新的答案。 – Sam

3

有兩種方法可以考慮 - 我會測試兩種方法,看看哪種方法對您的情況更好。

  1. 在子查詢中使用ROW_NUMBER()查找所有價格變化的最新價格變化,然後將其加入價格以得到正確的價格。
  2. 使用相關子查詢(很多這樣的方式,無論是在SELECT在其他的答案或與OUTER APPLY)僅獲取價格

如果你的價格表是非常大的,你的每一行最近的價格變化同時獲得大量價格,方法#1可能會更好,因此相關子查詢不會爲結果集的每一行運行。

如果您的最終查詢拉回相對較少的記錄而不是您的服務器的巨大結果集,則相關的子查詢可能會更好。

1. ROW_NUMBER()方法

SELECT 
    P.ID, 
    COALESCE(PC.NewCostPrice, P.Cost) AS LatestPrice 
FROM Price AS P 
    LEFT OUTER JOIN (
     SELECT 
      ID, 
      ROW_NUMBER() OVER (PARTITION BY ID 
       ORDER BY [Date] DESC) AS RowId, 
      NewCostPrice 
     FROM PriceChange 
    ) PC 
     ON P.ID = PC.ID 
      AND PC.RowId = 1 -- Only most recent 

2a上。相關子查詢(SELECT

SELECT 
    P.ID, 
    COALESCE((
     SELECT TOP 1 
      NewCostPrice 
     FROM PriceChange PC 
     WHERE PC.ID = P.ID 
     ORDER BY PC.[Date] DESC 
    ), P.Cost) AS LatestPrice 
FROM Price AS P 

2b中。與OUTER APPLY

SELECT 
    P.ID, 
    COALESCE(PC.NewCostPrice, P.Cost) AS LatestPrice 
FROM Price AS P 
    OUTER APPLY (
     SELECT TOP 1 
      NewCostPrice 
     FROM PriceChange PC 
     WHERE PC.ID = P.ID 
     ORDER BY PC.[Date] DESC 
    ) PC 

相關子查詢是否使用2a或2b更可能發生在你想如何保持查詢前進的偏好。

0

這裏我假設PC.ID不是主鍵,或者與ID聯繫在一起,但同一個項目上的價格可能不同。

從查詢我以爲你只是想獲取最新NewCostPrice通過Date排序,由所提到的表中加入priceChange

SELECT 
    P.ID, 
    CASE 
     WHEN PC.NewCostPrice IS NULL THEN P.Cost 
     ELSE PC.NewCostPrice      
    END AS NewPrice 
FROM 
    price AS P 
LEFT JOIN 
    (SELECT *, RANK() OVER (PARTITION BY ID ORDER BY [Date] DESC) as rk FROM priceChange) PC ON P.ID = PC.ID AND PC.rk = 1