Как проверить наличие строки перед объединением наборов данных (SQL Сервер) - PullRequest
1 голос
/ 18 июня 2020

Я пытаюсь объединить два набора данных и хочу проверить, существует ли уже строка в одной из таблиц.

Здесь я хотел бы выбрать все из table_1, которого еще нет в table_2 соответствие по 3 значениям столбца.

Таблица 1

| id | key   | value   |
|----|-------|---------| 
| 1  | brand | alpha   |
| 1  | color | red     |
| 2  | brand | charlie |

Таблица 2

| id | key   | value   |
|----|-------|---------| 
| 2  | brand | charlie |
| 2  | color | yellow  |

Желаемый результат

| id | key   | value   |
|----|-------|---------| 
| 2  | color | yellow  |

Запрос

select [id], [key], [value]
from db..table_1
where not exists (
  select
  [id], [key], [value]
  from db..table_2
)

Как добиться этого на сервере SQL?

1 Ответ

2 голосов
/ 18 июня 2020

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

-- except
SELECT [id], [key], [value] FROM dbo.table_1
EXCEPT
SELECT [id], [key], [value] FROM dbo.table_2;

-- not exists (must be correlated to t1!)
SELECT [id], [key], [value] 
FROM dbo.table_1 AS t1
WHERE NOT EXISTS
(
  SELECT 1 FROM dbo.table_2 AS t2
    WHERE t2.[id]    = t1.[id]
      AND t2.[key]   = t1.[key]
      AND t2.[value] = t1.[value]
);

-- left outer join    
SELECT t1.[id], t1.[key], t1.[value]
  FROM dbo.table_1 AS t1
  LEFT OUTER JOIN dbo.table_2 AS t2
       ON t2.[id]    = t1.[id]
      AND t2.[key]   = t1.[key]
      AND t2.[value] = t1.[value]
 WHERE t2.[id] IS NULL;

Некоторые здесь аспекты производительности .

Если у вас разные сопоставления между таблицами, вы можете разрешить конфликт с помощью предложения COLLATE, но вам нужно быть уверенным, что вы сопоставляете правильное сопоставление с сравните значения так, как вы ожидаете (помня, что при сопоставлении с чувствительным к регистру или двоичным сопоставлением, banana <> BANANA).

CREATE TABLE dbo.t1(a nvarchar(32) COLLATE Slovenian_BIN);

CREATE TABLE dbo.t2(a nvarchar(32) COLLATE Latin1_General_CS_AS_KS_WS);

SELECT a FROM dbo.t1 
EXCEPT 
SELECT a COLLATE Slovenian_BIN FROM dbo.t2;
         ---------------------
...