Я знаю, что опаздываю на вечеринку, но я работаю над изучением SQL, и я хотел попробовать свои силы в решении и сравнить с существующими ответами. Я создал таблицу Personnel
с некоторыми данными тестирования.
Мой запрос только к SQL Server использует CTE и INNER JOIN
:
WITH
Finance AS (SELECT SSN, Name FROM Personnel WHERE Org = 'Finance'),
IT AS (SELECT SSN, Name FROM Personnel WHERE Org = 'IT')
SELECT Finance.SSN, Finance.Name
FROM Finance
INNER JOIN IT ON IT.SSN = Finance.SSN
WHERE IT.Name != Finance.Name
Решение Александра использует прямую INNER JOIN
. Я переписал его немного, поместив сравнение имен в предложение WHERE
и добавив DISTINCT
, потому что это не требуется:
SELECT Finance.SSN, Finance.Name
FROM Personnel Finance
INNER JOIN Personnel IT ON Finance.SSN = IT.SSN
WHERE
(Finance.Org = 'Finance' AND IT.Org = 'IT') AND
(Finance.Name != IT.Name)
Решение Andomar с использованием коррелированного подзапроса в предложении EXISTS
:
SELECT SSN, Name
FROM Personnel a
WHERE
(Org = 'Finance') AND
EXISTS
(
SELECT *
FROM Personnel b
WHERE (Org = 'IT') AND (a.SSN = b.SSN) AND (a.Name != b.Name)
)
решение Барриллойда с использованием коррелированного подзапроса в предложении IN
:
SELECT SSN, Name
FROM Personnel p1
WHERE
(Org = 'Finance') AND
SSN IN
(
SELECT SSN FROM Personnel p2
WHERE (Org = 'IT') AND (p1.Name != p2.Name)
)
Я подключил все это к SQL Server, и оказалось, что запросы 1 и 2 генерируют один и тот же план запросов, а запросы 3 и 4 генерируют один и тот же план запросов. Разница между этими двумя группами заключается в том, что первая группа фактически выполняет INNER JOIN
внутри, тогда как вторая группа вместо этого выполняет левое полусоединение. ( См. Здесь для объяснения различных типов соединений.)
Я предполагаю, что есть преимущество в производительности незначительное в пользу левого полусоединения; однако для бизнес-случая, если вы хотите увидеть какие-либо столбцы данных из правой таблицы (например, если вы хотите отобразить оба имен для их сравнения), вам придется полностью переписать эти запросы в используйте решение на основе INNER JOIN
.
Итак, учитывая все это, я бы предпочел решение 2, потому что производительность очень похожа на 3 и 4, и она гораздо более гибкая, чем те. Мое решение делает оператор SELECT
очень легко читаемым, но он более многословен, чем 2 и не так переносим. Я полагаю, что мой может быть лучше для удобочитаемости, если вам нужно выполнить дополнительную фильтрацию для каждой из двух «вложенных таблиц», или если результаты этого запроса будут использоваться в качестве промежуточного шага для дальнейшей цели.