Вероятно, наиболее тщательный запрос таков:
SELECT table1.id,
table1.digit,
table1.letter
FROM ( SELECT id,
digit,
letter,
ROW_NUMBER() OVER (PARTITION BY digit, letter ORDER BY id) rn
FROM table1
) table1
LEFT
JOIN ( SELECT id,
digit,
letter,
ROW_NUMBER() OVER (PARTITION BY digit, letter ORDER BY id) rn
FROM table2
) table2
ON table2.digit = table1.digit
AND table2.letter = table1.letter
AND table2.rn = table1.rn
WHERE table2.id IS NULL
ORDER
BY table1.id
;
, который дает каждой записи в table1
и table2
"номер строки" в своей группе "двойников".Например, это:
SELECT id,
digit,
letter,
ROW_NUMBER() OVER (PARTITION BY digit, letter ORDER BY id) rn
FROM table1
ORDER
BY table1.id
;
возвращает это:
ID DIGIT LETT RN
---------- ---------- ---- ----------
1 4 S 1
2 2 P 1
3 5 B 1
4 4 S 2 -- second row with 4 S
5 1 A 1
6 2 P 2 -- second row with 2 P
Тем не менее, если вы знаете, что (digit, letter)
не может появиться более одного раза в table2
, вы можетезначительно упростить это, используя EXISTS
вместо ROW_NUMBER()
:
SELECT id,
digit,
letter
FROM table1 table1a
WHERE EXISTS
( SELECT 1
FROM table1
WHERE digit = table1a.digit
AND letter = table1a.letter
AND id < table1a.id
)
OR NOT EXISTS
( SELECT 1
FROM table2
WHERE digit = table1a.digit
AND letter = table1a.letter
)
;