У меня есть таблица в этой структуре. Я пытаюсь найти все уникальные идентификаторы, слова которых не отображаются в списке. Как я могу добиться этого в MS SQL Server.

id word
1  hello
2  friends
2  world
3  cat
3  dog
2  country
1  phone
4  eyes

У меня есть список слов

**List**

phone 
eyes
hair
body

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

За исключением слов из списка, мне нужны все уникальные идентификаторы. В этом случае это,

2
3


I & 4 не выводятся, поскольку их слова отображаются в списке

Я попробовал приведенный ниже код

Select count(distinct ID)
from Table1
where word not in ('phone','eyes','hair','body')

Я пробовал Not Exists также, который не работал

3
terry 13 Мар 2019 в 19:14

5 ответов

Лучший ответ

Вы также можете попробовать это: это динамическая структура таблицы:

DECLARE @T AS TABLE (id int, word varchar(20))
INSERT INTO @T VALUES
(1, 'hello'),
(2, 'friends'),
(2, 'world'),
(3, 'cat'),
(3, 'dog'),
(2, 'country'),
(1, 'phone'),
(4, 'eyes')

DECLARE @tblNotUsed AS TABLE ( id int, word varchar(20))
DECLARE @tblNotUsedIds AS TABLE (id int)

INSERT INTO @tblNotUsed VALUES
(1, 'phone'),
(2, 'eyes'),
(3, 'hair'),
(4, 'body')

INSERT INTO @tblNotUsedIds (id) 
SELECT [@T].id FROM @T INNER JOIN @tblNotUsed ON [@tblNotUsed].word = [@T].word

SELECT DISTINCT id FROM @T 
WHERE id NOT IN (SELECT id FROM @tblNotUsedIds)
1
Hasan Mahmood 13 Мар 2019 в 16:32

Вы также можете использовать GROUP BY

SELECT id
FROM Table1
GROUP BY id 
HAVING MAX(CASE WHEN word IN('phone', 'eyes', 'hair', 'body') THEN 1 ELSE 0 END) = 0
8
Martin Smith 13 Мар 2019 в 16:22

Один из способов сделать это - использовать not exists, где внутренний запрос связан с внешним запросом по id и фильтруется поисковыми словами.

Сначала создайте и заполните таблицу примеров ( Пожалуйста, сохраните этот шаг в своих будущих вопросах):

DECLARE @T AS TABLE (
    id int, 
    word varchar(20)
)
INSERT INTO @T VALUES
(1, 'hello'),
(2, 'friends'),
(2, 'world'),
(3, 'cat'),
(3, 'dog'),
(2, 'country'),
(1, 'phone'),
(4, 'eyes')

Запрос:

SELECT DISTINCT id
FROM @T t0
WHERE NOT EXISTS
(
    SELECT 1
    FROM @T t1
    WHERE word IN('phone', 'eyes', 'hair', 'body')
    AND t0.Id = t1.Id
)

Результат:

id
2
3
5
Zohar Peled 13 Мар 2019 в 16:20

Хорошая вещь в SQL - иногда есть много способов сделать что-то. Вот один из способов - поместить список известных значений в таблицу #temp, а затем запустить что-то вроде этого.

Select * from dbo.maintable

EXCEPT

Select * from #tempExcludeValues

В результате вы получите все записи, которых нет в вашем заранее заданном списке. Второй способ - сделать соединение, как Ларну упоминал в комментарии выше. NOT IN, как правило, не самый быстрый способ работы с большими наборами данных. СОЕДИНЕНИЯ - самый эффективный метод фильтрации данных. Во много раз лучше, чем использование предложения IN или NOT IN.

0
Steven Johnson 13 Мар 2019 в 16:21
SELECT t.id FROM dbo.table AS t
  WHERE NOT EXISTS (SELECT 1 FROM dbo.table AS t2
    INNER JOIN 
      (VALUES('phone'),('eyes'),('hair'),('body')) AS lw(word)
    ON t2.word = lw.word
    AND t2.id = t.id)
GROUP BY t.id;
4
Aaron Bertrand 13 Мар 2019 в 16:21