ВЫБЕРИТЕ все, чего нет в другой таблице - PullRequest
2 голосов
/ 20 марта 2009

Я унаследовал менее чем идеальную структуру таблицы, и я пытаюсь улучшить ее настолько, насколько смогу, не разрушая и не перестраивая. В настоящее время существует как минимум два уровня данных для всего: устаревшие данные и данные переопределения маркетинга. Я пытаюсь найти все записи в унаследованных данных, у которых еще нет маркетингового переопределения.

Пока что вот что у меня есть:

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 записей
  • В маркетинговой таблице около 7000
  • И STYLE_NBR, и COLOR_NBR являются символами (5) и при объединении создают уникальный идентификатор.

Ответы [ 8 ]

4 голосов
/ 20 марта 2009

Вы должны использовать 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
2 голосов
/ 20 марта 2009

То, что у вас есть в данный момент, неверно, потому что он будет возвращать строку для каждой строки, которая не соответствует , поэтому, возможно, 6999 строк в результате на строку в устаревшей таблице при наличии переопределения маркетинга или 7000, если нет. отличные затем отбрасывают дубликаты, но результат будет неправильным, потому что даже если есть строка соответствия маркетинга, несовпадающие будут гарантировать, что набор результатов будет включать те, где нет строки.

Попробуйте вместо этого:

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).

1 голос
/ 20 марта 2009

Некоторые варианты:

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
)

РЕДАКТИРОВАТЬ: Ключевым моментом в обоих случаях является то, что вы присоединяетесь, используя = вместо <>.

1 голос
/ 20 марта 2009
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;

У вас больше шансов использовать индексы, которые у вас, по-видимому, есть для четырех рассматриваемых столбцов.

1 голос
/ 20 марта 2009

Я не знаю, будет ли это быстрее, но, возможно, стоит попробовать.

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
)
1 голос
/ 20 марта 2009

Индексируются ли поля объединения? Это должно значительно ускорить процесс. Убедитесь, что old.STYLE_NBR, old.COLOR_NBR, new.style_number и new.color_number проиндексированы.

0 голосов
/ 21 марта 2009

- А как же ИСКЛЮЧИТЬ? (если это SQL Server 2005 или 2008) выберите old.Style_NBR, Old.Color_NBR Кроме выберите new.Style_NBR, new.Color_NBR

- попробуйте код ниже в mssql 2008

объявить @Old table ( Color_Nbr tinyint, Style_Nbr tinyint )

объявить @New table ( 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

0 голосов
/ 20 марта 2009

А как насчет НЕ СУЩЕСТВУЕТ?

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...