Справка SQL: найдите, какие столбцы вызвали несоответствие - PullRequest
2 голосов
/ 23 января 2010

Запрос ниже выбирает строки из таблицы_1, которых нет в таблице_2, на основе значений в 4 столбцах. Несоответствие может быть связано с одним или несколькими столбцами.

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

SELECT  i.agent ,
        i.agency ,
        i.customer ,
        i.Company
FROM    table_1 AS i
WHERE   NOT EXISTS ( SELECT p.agent ,
                            p.agency ,
                            p.customer ,
                            p.Company
                     FROM   table_2 AS p
                     WHERE  i.Agent = p.Agent
                            AND i.agency = p.Agency
                            AND i.customer = p.customer
                            AND i.Company = p.Company )

Обновление: Я предполагаю, что это требует большей доработки. Давайте добавим, что 3 из 4 столбцов должны совпадать.

Ответы [ 3 ]

2 голосов
/ 23 января 2010

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

Допустим, вы ожидаете agent иagency для совпадения, но customer и company могут не совпадать.Это не так уж сложно:

SELECT
    i.agent, i.agency, i.customer, i.company, p.customer, p.company,
    CASE
        WHEN i.customer = p.Customer THEN 'Y'
        ELSE 'N'
    END AS matchescustomer,
    CASE
        WHEN i.company = p.Company THEN 'Y'
        ELSE 'N'
    END AS matchescompany
FROM table1 i
INNER JOIN table2 p
    ON p.agent = i.agent
    AND p.agency = i.agency

Если вы хотите проверить другие частичные совпадения, просто измените порядок столбцов.Вместо объединения в agent и agency, присоединение в agent и customer или что-либо еще.

Если вы ожидаете только несколько различных типов частичных совпадений, вы можете написать несколько разных запросов.аналогично приведенному выше и сложите их вместе с UNION (или UNION ALL, если вы не возражаете против дубликатов).Другими словами:

SELECT (columns)
FROM table1 i INNER JOIN table2 p
    ON p.agent = i.agent AND p.agency = i.agency
UNION
SELECT (columns)
FROM table1 i INNER JOIN table2 p
    ON p.agent = i.agent AND p.customer = i.customer

Теперь, если вы хотите получить каждое возможное несоответствие , тогда это быстро выйдет из-под контроля, так что вы можете адаптировать болееэвристический метод и поиск частичных совпадений, которые соответствуют не менее определенному количеству столбцов (скажем, 3).Тогда вы можете ограничить несносность не более чем числом столбцов, которые вы должны сравнить:

;WITH PartialMatches_CTE AS
(
    SELECT i.agent AS iagent, p.agent AS pagent, ... (etc.)
    FROM table1 i INNER JOIN table2 p ON p.agent = i.agent
    UNION ALL
    SELECT (...) FROM table1 INNER JOIN table2 ON p.agency = i.agency
    UNION ALL
    SELECT (...) FROM table1 INNER JOIN table2 ON p.company = i.company
    ... and so on
),
ResolvedMatches_CTE AS
(
    SELECT DISTINCT
        iagent, pagent, iagency, pagency, ...,
        CASE WHEN pagent = iagent THEN 'Y' ELSE 'N' END AS agentmatch,
        CASE WHEN pagency = iagency THEN 'Y' ELSE 'N' END AS agencymatch,
        ...,
        (CASE WHEN pagent = iagent THEN 1 ELSE 0 END +
         CASE WHEN pagency = iagency THEN 1 ELSE 0 END +
         ...) AS MatchCount
    FROM PartialMatches_CTE
)
SELECT *
FROM ResolvedMatches_CTE
WHERE MatchCount >= 3

Теперь, после всего сказанного, мне интересно одно ...

Эти две таблицы данных, возможно, не связаны последовательно, не так ли?Например, 3-я строка в таблице 1 всегда отображается на 3-ю строку в таблице 2, но может не соответствовать всем столбцам?Это выстрел в темноте, но если это действительно так, то мы могли бы сделать это способ проще.В противном случае последний запрос здесь, вероятно, должен делать то, что вы хотите, не превращаясь в слишком большую часть бесполезного беспорядка.

Обратите внимание, что производительность, вероятно, снизится для всех этих запросов.Надеюсь, ваши наборы данных не слишком велики.AFAIK, нет простого способа действительно оптимизировать подобные вещи.

1 голос
/ 23 января 2010

Как говорят другие, эту проблему нужно определить немного подробнее.

Допустим, у вас есть эти объекты в таблице 1:

  1. Большое красное сладкое яблоко
  2. Маленькое, зеленое, терпкое яблоко
  3. Средний, оранжевый, сладкий персик
  4. Средний, оранжевый, кислый мандарин

И эти предметы в таблице2:

  1. маленькая, красная, сладкая слива
  2. большое, красное, сладкое яблоко
  3. маленькая, зеленое, кислое яблоко
  4. маленькая, оранжеваясладкий мандарин

Теперь давайте пройдемся по таблице 1:

  1. Большое, красное, сладкое яблоко соответствует пункту 2 в таблице 2
  2. Маленький зеленый, у кислого яблока нет совпадений - какие столбцы не соответствуют?
    • таблица 2, пункт 1 - несоответствие по размеру, цвету, вкусу и фруктам
    • таблица 2, пункт 1 - несоответствие по размеру, цвету и вкусу
    • ...
    • ...
  3. (также не соответствует)
    • ...
    • ...
    • ...
    • ...
  4. (также не соответствует)
    • ...
    • ...
    • ...
    • ...

Как видите, это очень быстро становится экспоненциальной проблемой.Имея всего четыре элемента в каждом списке, у вас есть 12 несоответствующих пар для столбцов списка.Если бы у вас было 100 000 элементов, а 10 000 были несовпадающими, вам нужно было бы перечислить 100 миллионов пар.

Если вы переопределите свой запрос, чтобы в нем были перечислены только элементы, отличающиеся по атрибуту один (столбец), тогда это может быть немного более выполнимо.Примерно так:

-- warning untested code --

         SELECT 'agent' AS MismatchedColumn ,
                p.agent AS MismatchedValue ,
                i.agent ,
                i.agency ,
                i.customer , 
                i.company
           FROM table_1 AS i
LEFT OUTER JOIN table_2 AS p
             ON i.agent != p.agent
                AND i.agency = p.agency
                AND i.customer = p.customer
                AND i.company = p.company
          UNION
         SELECT 'agency' AS MismatchedColumn ,
                p.agency AS MismatchedValue ,
                i.agent ,
                i.agency ,
                i.customer ,
                i.company
           FROM table_1 AS i
LEFT OUTER JOIN table_2 AS p
             ON i.agent = p.agent
                AND i.agency != p.agency
                AND i.customer = p.customer
                AND i.company = p.company
          UNION
         SELECT 'customer' AS MismatchedColumn ,
                p.customer AS MismatchedValue ,
                i.agent ,
                i.agency ,
                i.customer ,
                i.company
           FROM table_1 AS i
LEFT OUTER JOIN table_2 AS p
             ON i.agent = p.agent
                AND i.agency = p.agency
                AND i.customer != p.customer
                AND i.company = p.company
          UNION
         SELECT 'company' AS MismatchedColumn ,
                p.company AS MismatchedValue ,
                i.agent ,
                i.agency ,
                i.customer ,
                i.company
           FROM table_1 AS i
LEFT OUTER JOIN table_2 AS p
             ON i.agent = p.agent
                AND i.agency = p.agency
                AND i.customer = p.customer
                AND i.company != p.company

Полагаю, здесь будут перечислены все записи в таблице 1, которые совпадают по всем столбцам в таблице, кроме одного.

0 голосов
/ 23 января 2010

Это четко определено? если [1,2,3,4] и [5,2,3,5] существуют в p, то [1,2,3,5] в i является несоответствием [1,2,3,4] по столбцу г и несоответствие [5,2,3,5] по столбцу а. Или вы утверждаете, что это несоответствие из-за d и a?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...