簡體   English   中英

多次連接到同一張表時的條件連接和查詢優化

[英]Conditional Joining and query optimization when joining to the same table multiple times

我們的數據庫中有兩個表。 該查詢中的主表是Asset。 它與稱為AssetListing的表具有一對多關系。 AssetListing表中具有多個日期和數字字段,並且當前我們有一個報表,該報表設置為獲取每個日期之一,在某些情況下,還可以從AssetListing表中獲取一個數值,其中日期不為null。 需要注意的是,在特定日期不為空的每種情況下,我們都希望獲取與最新的AssetListingId相關聯的日期(AssetListing上的PK)。 該查詢當前如下所示:

SELECT A.AssetNumber
        , CLP.CurrentListPrice
, CLP.CurrentListPriceDate
, ListingExpirationDate = LXP.ExpirationDate
, LPC.ListPriceChange
, LPC.ListPriceChangeDate
FROM Asset A
LEFT JOIN
    (
        SELECT AssetNumber
            , AssetListingId
            , CurrentListPrice
            , CurrentListPriceDate
            , ROW_Num = ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC)
        FROM [dbo].AssetListing WITH (NOLOCK)
        WHERE CurrentListPrice IS NOT NULL
    ) CLP ON CLP.AssetNumber = A.AssetNumber AND CLP.ROW_NUM = 1
LEFT JOIN
    (
        SELECT AssetNumber
            , AssetListingId
            , ExpirationDate
            , ROW_Num = ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC)
        FROM [dbo].AssetListing WITH (NOLOCK)
        WHERE ExpirationDate IS NOT NULL
    ) LXP ON LXP.AssetNumber = A.AssetNumber AND LXP.ROW_NUM = 1
LEFT JOIN
    (
        SELECT AssetNumber
            , AssetListingId
            , CurrentListPrice
            , ListPriceChange
            , ListPriceChangeDate
            , ROW_Num = ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC)
        FROM [dbo].AssetListing WITH (NOLOCK)
        WHERE ListPriceChange IS NOT NULL
    ) LPC ON LPC.AssetNumber = A.AssetNumber AND LPC.ROW_NUM = 1

必須有一種方法可以通過單個聯接來執行此操作,但是我不確定如何執行此操作。 我們需要每個聯接的日期,在某些情況下,我們還需要一個數值。 您如何優化此查詢?

嘗試此操作,其想法是根據行號獲取每個資產號最多只能有一個結果的最大值。

SELECT A.AssetNumber
    , CurrentListPrice      = MAX(CASE WHEN CPRN = 1 THEN CurrentListPrice END)
    , CurrentListPriceDate  = MAX(CASE WHEN CPRN = 1 THEN CurrentListPriceDate END)
    , ListingExpirationDate = MAX(CASE WHEN EPRN = 1 THEN ExpirationDate END)
    , ListPriceChange       = MAX(CASE WHEN EPRN = 1 THEN ExpirationDate END)
    , ListPriceChangeDate   = MAX(CASE WHEN EPRN = 1 THEN ExpirationDate END)
FROM Asset A
JOIN (
    SELECT AssetNumber
        , AssetListingId
        , CurrentListPrice
        , CurrentListPriceDate
        , ExpirationDate
        , ListPriceChange
        , ListPriceChangeDate
        , CPRN = CASE WHEN CurrentListPrice IS NOT NULL 
                      THEN ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC) END
        , EPRN = CASE WHEN ExpirationDate IS NOT NULL 
                      THEN ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC) END
        , LPRN = CASE WHEN ListPriceChange IS NOT NULL 
                      THEN ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC) END
    FROM dbo.AssetListing WITH (NOLOCK)
) AL ON AL.AssetNumber = A.AssetNumber
GROUP BY A.AssetNumber

實際上,這里的聯接實際上並不是必需的,但是為了簡單起見,我已經保留了它。

暫無
暫無

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

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