2013-02-08 19 views
1

我有一個T-SQL查詢在SQL Server 2005上運行,我已經定義了一個數據表來返回給應用程序。如何將SQL Server查詢邏輯整合到一個案例中?

我使用幾個case語句分配幾個值,每個case語句具有相同的邏輯。

我想知道是否有辦法讓這個更高效,而不是多次執行相同的邏輯?我在這裏縮寫了邏輯,但希望能夠說明問題。有沒有一種方法可以不必使用相同的「pt.PTYP_Category IN(90,92,94,96,98)」邏輯定義三個案例語句?

`INSERT INTO @MemberAccountingDetail 
    (
    MACD_DPST_FEES_RowID, 
    MACD_HighOrderSort, 
    MACD_CategorySortDate, 
    MACD_MemberName 
    ) 
SELECT 
    d.DPST_ID As MACD_DPST_FEES_RowID, 
    CASE 
     WHEN pt.PTYP_Category IN (90, 92, 94, 96, 98) 
      THEN 0 
     ELSE  1 
    END As MACD_HighOrderSort, 
    CASE 
     WHEN pt.PTYP_Category IN (90, 92, 94, 96, 98) 
      THEN DATEADD(ss, 1, d.DPST_TransactionDate) 
     ELSE  @DefaultDate 
    END As MACD_CategorySortDate, 
    CASE 
     WHEN pt.PTYP_Category IN (90, 92, 94, 96, 98) 
      THEN pt.PTYP_CategoryDesc 
     ELSE  SUBSTRING(ISNULL(d.DPST_OriginUserID, ''), 1, 11) 
    END As MACD_MemberName 
FROM 
    Deposit d 
     INNER JOIN PaymentType pt 
      ON pt.PTYP_ID = d.DPST_PTYP_ID 
WHERE 
    d.DPST_MEMB_ID = @MEMB_ID; 

謝謝 吉姆`

+0

根據:HTTP:// stackoverflow.com/questions/2072721/how-can-i-select-multiple-columns-within-a-case-when-on-sql-server,以及:http://stackoverflow.com/questions/8358642/case-聲明在SQL中如何返回多個變量,它看起來像你運氣不好 – mcalex

+0

是的,這看起來像相同類型的東西。我想確保我不會錯過任何東西,因爲我不是專家。謝謝你指出這個問題。我很害怕這個!吉姆:) –

+1

我可以做的一件事是添加另一列到我的類別表中,我可以在這裏查詢單個字段而不是五個字段。如果需要,我會考慮。再次感謝您的其他參考。 –

回答

1

您可以使用公用表表達式,所以你只需要編寫的「報表」一次:

INSERT INTO @MemberAccountingDetail 
(
    MACD_DPST_FEES_RowID, 
    MACD_HighOrderSort, 
    MACD_CategorySortDate, 
    MACD_MemberName 
) 
WITH CTE (PTYP_ID, IsInCollection) 
AS 
(
    SELECT pt.PTYP_ID, CASE WHEN pt.PTYP_Category IN (90, 92, 94, 96, 98) THEN 0 ELSE 1 END AS IsInCollection 
    FROM PaymentType pt 
) 
SELECT 
    d.DPST_ID As MACD_DPST_FEES_RowID, 
    CTE.IsInCollection As MACD_HighOrderSort, 
    CASE WHEN CTE.IsInCollection = 1 
     THEN DATEADD(ss, 1, d.DPST_TransactionDate) 
     ELSE  @DefaultDate 
    END As MACD_CategorySortDate, 
    CASE WHEN CTE.IsInCollection = 1 
     THEN pt.PTYP_CategoryDesc 
     ELSE SUBSTRING(ISNULL(d.DPST_OriginUserID, ''), 1, 11) 
    END As MACD_MemberName 
FROM Deposit d 
INNER JOIN CTE 
    ON CTE.PTYP_ID = d.DPST_PTYP_ID 
INNER JOIN PaymentType pt 
    ON pt.PTYP_ID = d.DPST_PTYP_ID 
WHERE d.DPST_MEMB_ID = @MEMB_ID; 
+0

Geert,這很有趣,看起來像我一直在尋找。我以前沒見過CTE。我將與此合作並接受此爲解決方案。謝謝,吉姆 –

0

你可以嘗試使用UNION,使兩種地分居選擇,但我不知道它會更快:

INSERT INTO @MemberAccountingDetail 
    (
    MACD_DPST_FEES_RowID, 
    MACD_HighOrderSort, 
    MACD_CategorySortDate, 
    MACD_MemberName 
    ) 

SELECT 
    d.DPST_ID As MACD_DPST_FEES_RowID, 
    0 As MACD_HighOrderSort, 
    DATEADD(ss, 1, d.DPST_TransactionDate) As MACD_CategorySortDate, 
    pt.PTYP_CategoryDesc As MACD_MemberName 
FROM 
    Deposit d 
     INNER JOIN PaymentType pt 
      ON pt.PTYP_ID = d.DPST_PTYP_ID 
WHERE 
    d.DPST_MEMB_ID = @MEMB_ID and pt.PTYP_Category IN (90, 92, 94, 96, 98) 
UNION ALL 
SELECT 
    d.DPST_ID As MACD_DPST_FEES_RowID, 
    1 As MACD_HighOrderSort, 
    @DefaultDate As MACD_CategorySortDate, 
    SUBSTRING(ISNULL(d.DPST_OriginUserID, ''), 1, 11) as MACD_MemberName 
FROM 
    Deposit d 
     INNER JOIN PaymentType pt 
      ON pt.PTYP_ID = d.DPST_PTYP_ID 
WHERE 
    d.DPST_MEMB_ID = @MEMB_ID and pt.PTYP_Category NOT IN (90, 92, 94, 96, 98) 
+0

是的,其實我已經有一個聯合會(未顯示),所以我實際上需要在我的情況下四個選擇的聯合。哎喲!感謝您指出這一點。我想在我的分類表中添加更高級別的字段是提高效率的方法。我想我不會錯過某些明顯的問題。謝謝 –

0

您可以創建一個您的表中的計算列將這5個類別彙總爲一個代碼,然後使用它。

這意味着您不必再使用硬編碼魔術數字。但你仍然需要四種不同的案例陳述。這是任何試圖解決它的「聰明」嘗試只會讓它變得更加複雜的事情之一。

0

還有一個與CROSS選項會被應用

INSERT INTO @MemberAccountingDetail 
    (
    MACD_DPST_FEES_RowID, 
    MACD_HighOrderSort, 
    MACD_CategorySortDate, 
    MACD_MemberName 
    ) 
SELECT 
    d.DPST_ID As MACD_DPST_FEES_RowID, 
    CASE WHEN o.IsMatch = 1 THEN 0 
     ELSE 1 END As MACD_HighOrderSort, 
    CASE WHEN o.IsMatch = 1 THEN DATEADD(ss, 1, d.DPST_TransactionDate) 
     ELSE @DefaultDate END As MACD_CategorySortDate, 
    CASE WHEN o.IsMatch = 1 THEN pt.PTYP_CategoryDesc 
     ELSE SUBSTRING(ISNULL(d.DPST_OriginUserID, ''), 1, 11) END As MACD_MemberName 
FROM Deposit d INNER JOIN PaymentType pt ON pt.PTYP_ID = d.DPST_PTYP_ID 
       CROSS APPLY (SELECT CASE WHEN pt.PTYP_Category IN (90, 92, 94, 96, 98) THEN 1 END AS IsMatch) o 
WHERE d.DPST_MEMB_ID = @MEMB_ID;