SELECT所有不在另一个表中的

时间:2009-03-20 15:20:06

标签: sql sql-server

我继承了一个不太理想的表结构,我正试图尽可能地改进它而不会拆除和重建。目前,所有内容,遗留数据和营销覆盖数据至少有两个级别的数据。我正在尝试查找遗留数据中尚未进行营销覆盖的所有记录。

到目前为止,这就是我所拥有的:

SELECT DISTINCT 
  old.STYLE_NBR, old.COLOR_NBR 
FROM 
  LEGACY_PRODUCT_TABLE old
INNER JOIN 
  MARKETING_PRODUCT_TABLE new
ON old.STYLE_NBR <> new.style_number AND old.COLOR_NBR <> new.colour_number

这似乎有效,但运行需要几分钟。如果可能的话,我想要一种更有效的方法。

其他信息:

  • 旧表中有大约60,000条记录
  • 营销表中约有7,000个
  • STYLE_NBRCOLOR_NBR都是char(5),合并后,会创建一个唯一的ID。

8 个答案:

答案 0 :(得分:4)

您应该使用LEFT OUTER JOIN并更改查找

SELECT DISTINCT 
  old.STYLE_NBR, old.COLOR_NBR 
FROM 
  LEGACY_PRODUCT_TABLE old
  LEFT OUTER JOIN MARKETING_PRODUCT_TABLE new
    ON (old.STYLE_NBR + old.COLOR_NBR) = (new.style_number + new.Colour_number)
WHERE (new.style_number + new.Colour_number) IS NULL

答案 1 :(得分:2)

您当前拥有的内容不正确,因为它会为匹配的每一行返回一行,因此如果存在营销覆盖,则旧表中每行的结果可能为6999行,如果没有,则为7000。然后,distinct将丢弃重复项,但结果将是错误的,因为即使存在营销匹配行,不匹配的行也将确保结果集将包含没有行的那些。

请改为尝试:

select distinct style_nbr, color_nbr
 from legacy_product_table L
where not exists
(
   select * from marketing_product_table m
   where m.style_nbr = L.style_nbr and m.color_nbr = L.color_nbr
)

确保产品表上有一个索引(style_nbr,color_nbr)。

答案 2 :(得分:1)

联接字段是否已编入索引?这应该会大大加快速度。确保将old.STYLE_NBR,old.COLOR_NBR,new.style_number和new.color_number编入索引。

答案 3 :(得分:1)

我不知道这会更快,但值得一试。

SELECT DISTINCT 
  old.STYLE_NBR, old.COLOR_NBR 
FROM 
  LEGACY_PRODUCT_TABLE old
WHERE old.STYLE_NBR, old.COLOR_NBR 
NOT IN 
(
    SELECT old.STYLE_NBR, old.COLOR_NBR 
    FROM LEGACY_PRODUCT_TABLE old
    INNER JOIN 
        MARKETING_PRODUCT_TABLE new
        ON 
            old.STYLE_NBR == new.style_number AND old.COLOR_NBR == new.colour_number
)

答案 4 :(得分:1)

SELECT 
    old.* 
FROM 
    LEGACY_PRODUCT_TABLE old 
LEFT JOIN
    MARKETING_PRODUCT_TABLE new 
ON 
    new.style_number=old.STYLE_NBR AND 
    new.colour_number=old.COLOR_NBR 
WHERE 
    new.style_number IS NULL;

更有可能使用您可能在有关的四列上使用的索引。

答案 5 :(得分:1)

要尝试的一些选项是:

SELECT
    old.STYLE_NBR,
    old.COLOR_NBR
FROM  
    LEGACY_PRODUCT_TABLE old
LEFT OUTER JOIN
    MARKETING_PRODUCT_TABLE new
ON
    old.STYLE_NBR = new.style_number
AND
    old.COLOR_NBR = new.colour_number
WHERE
    new.style_number IS NULL



SELECT
    old.STYLE_NBR,
    old.COLOR_NBR
FROM  
    LEGACY_PRODUCT_TABLE old
WHERE
    NOT EXISTS
(
    SELECT
        *
    FROM
        MARKETING_PRODUCT_TABLE new
    WHERE
        old.STYLE_NBR = new.style_number
    AND
        old.COLOR_NBR = new.colour_number
)

编辑:这两个方面的关键是你使用=而不是&lt;&gt;加入。

答案 6 :(得分:0)

怎么样不存在?

SELECT DISTINCT old.STYLE_NBR, old.COLOR_NBR 
FROM LEGACY_PRODUCT_TABLE old
WHERE NOT EXISTS
    (SELECT 1 FROM MARKETING_PRODUCT_TABLE new 
    WHERE old.STYLE_NBR = new.style_number 
      AND old.COLOR_NBR = new.colour_number)

答案 7 :(得分:0)

- EXCEPT怎么样? (如果这是SQL Server 2005或2008) 选择old.Style_NBR,Old.Color_NBR 除了 选择new.Style_NBR,new.Color_NBR

- 在mssql 2008中尝试以下代码

声明@Old表(     Color_Nbr tinyint,     Style_Nbr tinyint )

声明@New表(     Color_Nbr tinyint,     Style_Nbr tinyint )

插入@Old 值(1,1),         (2,2),         (3,3),         (4,4)

插入@New 值(1,1),         (2,2),         (3,3),         (5,5)

选择o.Color_Nbr,     o.Style_Nbr 来自@Old o

除了

选择n.Color_Nbr,     n.Style_Nbr 来自@New n