Как бороться с дубликатами ключей - PullRequest
0 голосов
/ 05 декабря 2018

tblA

id

tblB

id, id2

Я хочу проверить, еслиtbl ID существует в tbl B ID, НО НЕ смотрите на id2, столбец id2 в tblB будет иметь ключи, которые присутствуют в tblA.

SELECT id
FROM tblA as a
WHERE NOT EXISTS 
(
SELECT * FROM tblB AS b
WHERE a.id = b.id
)

По логике это должно работать, но по некоторым причинам он также дает мне значения, которые присутствуют в столбце id2 в tblB, которых нет в идентификаторе tblA

Пример данных

tblA

ID 
1
2 
3
4 

tblB

tblb_ID   | ID2 
3         | 34
4         | 38 
12        | 93
43        | 54
54        | 4

Ожидаемый результат

1,2, потому что 1 и 2 не существует в tblB.

Что я получу,

Только 1, потому что 4 существует в ID2, почему это?

Ответы [ 4 ]

0 голосов
/ 05 декабря 2018

Описание столбцов в вашем tblB не соответствует образцу данных, который показывает первый столбец как tblb_ID.Если это правильное имя, то

SELECT id
FROM tblA as a
WHERE NOT EXISTS 
(
SELECT * FROM tblB AS b
WHERE a.id = b.id
)

недопустимо и должно быть помечено как синтаксическая ошибка, потому что b.id нет.Если это не так, у вас есть сообщение об ошибке.

Тем не менее, я бы изменил рекомендуемое исправление на

SELECT id
FROM tblA as a
WHERE NOT EXISTS 
(
    SELECT 1 FROM tblB AS b
    WHERE a.id = b.tblb_ID
)

, потому что это упрощает работу для обработчика запросов и улучшаетпередает ваше намерение.

Значение SELECT и, следовательно, SELECT * часто понимают неправильно.SELECT - это SQL-реализация PROJECT в реляционной алгебре: она указывает, какие столбцы (не строки) возвращать.SELECT * возвращает все столбцы;если бы SQL не был пережитком эпохи языков 4-го поколения, мы могли бы обойтись без SELECT *, потому что project all совпадает с no projection .

В тесте на существование проекция отсутствует, т. Е. столбцы не выбраны .Вся критическая информация находится в FROM и WHERE.Строка - вся строка - либо соответствует критерию WHERE, либо нет.Значение строки нигде не возвращается.Например, он не доступен для внешнего запроса.«Выбрать» бессмысленно;он существует только потому, что этого требует синтаксис.

Говоря SELECT 1, мы подчеркиваем, что это логический тест и что ничего не "выбирается" как таковое .

0 голосов
/ 05 декабря 2018

Примерно так:

SELECT a.id
FROM tblA AS a
LEFT JOIN tblB as b
ON a.id = b.id
WHERE b.id IS NULL

Что должно дать вам все значения из A, которых нет в B, только по сравнению с B.id

0 голосов
/ 05 декабря 2018

Должно быть очень просто, если я понимаю твой вопрос.Вам нужны только строки из tblA, где tblA.id не соответствует tblB.id.tblB.id2 не имеет значения.

 SELECT * FROM tblA WHERE id NOT IN (SELECT tblb_ID FROM tblB)

Как уже говорилось, ваш оригинальный запрос должен работать.Учитывая вашу обновленную информацию, это выглядит как правильный запрос:

SELECT id
FROM tblA as a
WHERE NOT EXISTS 
(
    SELECT * FROM tblB AS b
    WHERE a.id = b.tblb_ID
)
0 голосов
/ 05 декабря 2018

Попробуйте это:

SELECT id FROM tblA WHERE id IN (SELECT id FROM tblB) AND id NOT IN (SELECT id2 FROM tblB)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...