[英]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.