У меня есть таблица с:

sqlite> select * from lookup;
node|id
1|1
1|2
2|4
2|6
sqlite> select * from tag;
tagid|data
1|bar
2|baz
3|geek
4|foo
5|bank
6|auto

Я хотел бы найти идентификаторы в таблице тегов, которые не упоминаются в поиске. Я пробовал:

select id from tag where not exists (select tagid from lookup);
# I am expecting the following result: 3, 5

Но это ничего не возвращает. tagid - это внешний ключ к tag, может ли это быть источником проблемы? Подскажите, как это сделать в SQL?

1
oz123 13 Сен 2014 в 23:13
Хм, если tagid является внешним ключом для tag, почему он находится в той же таблице?
 – 
lxg
13 Сен 2014 в 23:16

2 ответа

Лучший ответ

Вам необходимо соотнести два запроса. Поскольку у вас есть это, вы просто спрашиваете, не существует ли ничего в таблице поиска.

select 
    id 
from 
    tag t
where 
    not exists (
        select
            'x'
        from
            lookup l
        where
            l.tagid = t.id -- correlation
    );

Вы также можете написать это, используя внешнее соединение

select
    t.id
from
    tag t
        left outer join
    lookup l
        on t.id = l.tagid
where
    l.tagid is null;

Некоторые базы данных имеют разные характеристики производительности для двух методов.

Удалить:

delete from
    tag
where
    not exists (
        select
            'x'
        from
            lookup l
        where
            l.tagid = tag.id
    );
2
Laurence 13 Сен 2014 в 23:45
Спасибо! это мне очень помогло.
 – 
oz123
13 Сен 2014 в 23:20
Кстати, как вы можете расширить это до прямого удаления?
 – 
oz123
13 Сен 2014 в 23:31
Оператор удаления дает мне ошибку. Однако DELETE FROM TAG WHERE ID in (select id from tag t where not exists (select id from lookup l where l.tagid = t.id) сработало.
 – 
oz123
13 Сен 2014 в 23:43

Вы запрашиваете идентификаторы из таблицы тегов, но ваш выбор использует идентификаторы из таблицы поиска. Вы должны выбрать идентификаторы тегов из таблицы тегов, чтобы эти идентификаторы НЕ входили в набор идентификаторов из таблицы поиска:

select tagid from tag where tagid not in (select id from lookup);
0
oz123 12 Окт 2020 в 17:23
Не могли бы вы отформатировать выбранные запросы? Так проще понять, что вы имеете в виду.
 – 
oz123
21 Фев 2017 в 19:30