【问题标题】:Changing SQL NOT IN to JOINS将 SQL NOT IN 更改为 JOINS
【发布时间】:2015-07-02 05:03:36
【问题描述】:

大家好,

我们的目标是获得一个脚本,该脚本将在中间表 (ProductTaxCategory) 中插入缺失的产品对 - TaxCategory

以下脚本可以正常工作,但我们正在努力寻找优化它的方法:

INSERT ProductTaxCategory
    (ProductTaxCategory_TaxCategoryId,ProductTaxCategory_ProductId)
SELECT 
    TaxCategoryId
    ,ProductId 
FROM Product pr
CROSS JOIN TaxCategory tx
WHERE pr.ProductId NOT IN 
(
    SELECT ProductTaxCategory_ProductId
    FROM ProductTaxCategory
) 
OR
pr.ProductId IN 
(
    SELECT ProductTaxCategory_ProductId 
    FROM ProductTaxCategory
) 
AND
tx.TaxCategoryId NOT IN 
(
    SELECT ProductTaxCategory_TaxCategoryId 
    FROM ProductTaxCategory 
    WHERE ProductTaxCategory_ProductId = pr.ProductId
 )

我们如何优化这个查询?

【问题讨论】:

  • MERGE 可能更适合您的情况

标签: sql join sql-server-2012 notin


【解决方案1】:

尝试类似(现在的完整声明):

INSERT INTO ProductTaxCategory
    (ProductTaxCategory_TaxCategoryId,ProductTaxCategory_ProductId)
SELECT TaxCategoryId, ProductId 
FROM Product pr CROSS JOIN TaxCategory tx
WHERE NOT EXISTS
       (SELECT 1 FROM ProductTaxCategory 
        WHERE ProductTaxCategory_ProductId     = pr.ProductId
        AND   ProductTaxCategory_TaxCategoryId = tx.TaxCategoryId)

EXISTS(SELECT 1 ... WHERE ID=...) 通常是 IN (SELECT ID FROM ... ) 构造的更好替代方案。

【讨论】:

  • 谢谢!与我的需要 1210 毫秒相比,这需要 160 毫秒的执行时间
【解决方案2】:

您可以使用ProductTaxCategory 执行LEFT JOIN 并检查NULLs

类似的东西。

INSERT ProductTaxCategory
(
    ProductTaxCategory_TaxCategoryId,
    ProductTaxCategory_ProductId
)
SELECT p.TaxCategoryId, p.ProductId 
FROM 
(
    SELECT TaxCategoryId, ProductId
    FROM Product pr
    CROSS JOIN TaxCategory tx
) p
LEFT JOIN ProductTaxCategory ptx
    ON P.TaxCategoryId = ptx.ProductTaxCategory_TaxCategoryId 
    AND P.ProductId = ptx.ProductTaxCategory_ProductId
WHERE ptx.ProductTaxCategory_ProductId IS NULL

【讨论】:

    【解决方案3】:

    使用CROSS JOINEXCEPT

    INSERT ProductTaxCategory(ProductTaxCategory_ProductId, ProductTaxCategory_TaxCategoryId)
    
    SELECT p.ProductID, tc.TaxCategoryId FROM Product p CROSS JOIN TaxCategory tc
    
    EXCEPT
    
    SELECT ProductTaxCategory_ProductId, ProductTaxCategory_TaxCategoryId  FROM ProductTaxCategory
    

    CROSS JOIN 将搜索所有可能的配对。 EXCEPT 将为您提供所缺少的东西。最后你可以INSERT他们上桌了。

    【讨论】:

    • OP 有两个不同的列:ProductTaxCategory_TaxCategoryId, ProductTaxCategory_ProductId
    猜你喜欢
    • 2011-01-02
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    相关资源
    最近更新 更多