2014-05-16 37 views
0

我想優化此查詢使用聯接,而不是此子查詢,但與Top 1,我有點困惑。我如何能移動此選擇語句與頂部

SELECT 
    s.ItemNumber 
    s.ImportKey 
    ,(
     SELECT top 1 MerchandiseGroupID 
     FROM MerchandiseGroup mg 
     WHERE s.StoreDepartment = mg.Name AND c.ClientNumber = s.ClientNumber 
    ) as MerchandiseGroupID 
FROM dbo.Source s 
INNER JOIN dbo.Client c on s.ClientNumber = c.ClientNumber 
INNER JOIN dbo.ClientVendor cv on s.Vendor = cv.ClientVendorName 
INNER JOIN dbo.TypeClientWarehouse tw on c.WarehouseCode = tw.WarehouseCode 
WHERE s.ImportDate > '2014-05-15 01:00:00.000' 

我到目前爲止有:

INNER JOIN 
(
    SELECT 
     ROW_NUMBER() OVER (PARTITION BY Name ORDER BY MerchandiseGroupID asc) rnum, 
     MerchandiseGroupID, 
     Name 
    FROM MerchandiseGroup mg 
) mhg 
    ON s.StoreDepartment = mg.Name AND c.ClientNumber = s.ClientNumber 
WHERE s.ImportDate > '2014-05-15 01:00:00.000' AND mg.rnum = 1 
+0

不管你採用什麼方法,子查詢中的where子句將使其運行得更快。 –

回答

1

我認爲使用TOP 1爲不低於最優說但是如果你想加入的原因是把它變成一個加入和使用ROW_NUMBER()這樣你就可以從表中其他字段然後使用APPLY(你的第一個查詢具有與頂部沒有秩序,所以我假定這是相同的ROW_NUMBER函數在連接嘗試):

SELECT 
    s.ItemNumber, 
    s.ImportKey, 
    mg.MerchandiseGroupID, 
    mg.Name 
FROM dbo.Source s 
INNER JOIN dbo.Client c on s.ClientNumber = c.ClientNumber 
INNER JOIN dbo.ClientVendor cv on s.Vendor = cv.ClientVendorName 
INNER JOIN dbo.TypeClientWarehouse tw on c.WarehouseCode = tw.WarehouseCode 
OUTER APPLY 
(
    SELECT top 1 MerchandiseGroupID, Name 
    FROM MerchandiseGroup mg 
    WHERE s.StoreDepartment = mg.Name 
    AND c.ClientNumber = s.ClientNumber 
    ORDER BY MerchandiseGroupID 
) mg 
WHERE s.ImportDate > '2014-05-15 01:00:00.000' 

如果您只想要頂級1,則此方法通常比ROW_NUMBER更快,但如果您想要特定記錄(如第三條記錄)則靈活性較差。

沒有關係,但becareful使用你的日期格式時,即使這是ISO標準仍可引發錯誤:

SET DATEFORMAT DMY; 
SELECT CAST('2014-05-15 01:00:00.000' AS DATETIME); 

會給你:

Msg 242, Level 16, State 3, Line 2

The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.