Как проверить, совпадает ли содержимое двух столбцов из разных таблиц? - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть две таблицы в моей базе данных SQL. Я хочу проверить, имеют ли столбцы Specifier одинаковые данные в одном и том же порядке.

ОК, случай , поскольку обе таблицы содержат одинаковые данные в одинаковом порядке в Specifier столбец:

-- Table1:
RowID   Specifier
187     1         
188     1         
189     2         

-- Table2:
RowID   Specifier
181     1         
182     1         
183     2       

регистр ERROR , так как данные отличаются:

-- Table1:
RowID   Specifier
187     1         
188     2         
189     3         

-- Table2:
RowID   Specifier
181     1         
182     2         
183     2    

регистр ERROR , поскольку данныев другом порядке:

-- Table1:
RowID   Specifier
187     1         
188     1         
189     2         

-- Table2:
RowID   Specifier
181     1         
182     2         
183     1   

ОШИБКА case , поскольку различное количество данных:

-- Table1:
RowID   Specifier
187     1         
188     1         
189     2         

-- Table2:
RowID   Specifier
181     1         
182     1         
183     2
184     1       

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

IF EXISTS
    (SELECT Specifier FROM Table1 EXCEPT SELECT Specifier FROM Table2
    UNION ALL
    SELECT Specifier FROM Table2 EXCEPT SELECT Specifier FROM Table1)
BEGIN
    THROW 99999, 'Mismatching Specifiers between the two tables', 1;
END;

Ответы [ 2 ]

3 голосов
/ 08 ноября 2019

Вы можете использовать full join и row_number(). Следующее получает исключения:

select *
from (select t1.*, row_number() over (order by rowid) as seqnum
      from table1 t1
     ) t1 full join
     (select t2.*, row_number() over (order by rowid) as seqnum
      from table2 t2
     ) t2
     on t1.seqnum = t2.seqnum and t1.specifier = t2.specifier
where t1.seqnum is null or t2.seqnum is null;

Если вам просто нужен флаг:

select (case when count(*) > 1 then 1 else 0 end)
from (select t1.*, row_number() over (order by rowid) as seqnum
      from table1 t1
     ) t1 full join
     (select t2.*, row_number() over (order by rowid) as seqnum
      from table2 t2
     ) t2
     on t1.seqnum = t2.seqnum and t1.specifier = t2.specifier
where t1.seqnum is null or t2.seqnum is null;

Если вы заботитесь о производительности, использование первого запроса с exists должно быть быстрее.

0 голосов
/ 08 ноября 2019

Кажется, с

IF EXISTS (SELECT 1
           FROM (SELECT ROW_NUMBER() OVER (ORDER BY RowID) AS RN,
                        Specifier
                 FROM Table1) T1
                FULL OUTER JOIN (SELECT ROW_NUMBER() OVER (ORDER BY RowID) AS RN,
                                        Specifier
                                 FROM Table2) T2 ON T1.RN = T2.RN
                                                AND T1.Specifier = T2.Specifier
           HAVING COUNT(CASE WHEN T1.RN IS NULL OR T2.RN IS NULL THEN 1 END) >= 1) ...
это может быть проще
...