Есть много, много способов сделать это. Я помещаю некоторые (не печатая все это из изображения) данные в табличную переменную:
DECLARE @MyTable TABLE (PersonNumber VARCHAR(50), Code VARCHAR(50));
INSERT INTO @MyTable SELECT '4050100', '9210';
INSERT INTO @MyTable SELECT '4050100', '1020';
INSERT INTO @MyTable SELECT '2650100', '1020';
Вот пять способов получить нужный ответ:
SELECT DISTINCT m1.PersonNumber FROM @MyTable m1 LEFT JOIN @MyTable m2 ON m2.PersonNumber = m1.PersonNumber AND m2.Code = '9210' WHERE m2.PersonNumber IS NULL;
SELECT DISTINCT PersonNumber FROM @MyTable m1 WHERE NOT EXISTS (SELECT * FROM @MyTable m2 WHERE m2.PersonNumber = m1.PersonNumber AND m2.Code = '9210');
WITH x AS (SELECT DISTINCT PersonNumber FROM @MyTable WHERE Code = '9210') SELECT DISTINCT m.PersonNumber FROM @MyTable m LEFT JOIN x ON x.PersonNumber = m.PersonNumber WHERE x.PersonNumber IS NULL;
SELECT PersonNumber FROM @MyTable GROUP BY PersonNumber HAVING MAX(CASE WHEN Code = '9210' THEN 1 END) IS NULL;
SELECT PersonNumber FROM @MyTable GROUP BY PersonNumber HAVING MAX(CASE WHEN Code = '9210' THEN 1 ELSE 0 END) = 0;
Вкратце, вот как они работают:
- LEFT JOIN, чтобы проверить, что нет записи с кодом 9210 для того же номера человека
- НЕ СУЩЕСТВУЕТ - в основном те же логики c, но может быть проще следовать?
- Используя выражение общей таблицы, чтобы сначала идентифицировать 9210-е, а затем найти любые случаи, когда нет совпадения
- Использование агрегации
- Использование агрегации в более легкой для понимания query
Я провел очень, очень грубый анализ, и методы агрегации, похоже, немного лучше по производительности, чем другие методы, которые примерно одинаковы.