Python: используйте один sqlite-запрос, чтобы найти результат NOT EXISTS - PullRequest
0 голосов
/ 26 января 2020

У меня есть набор данных из миллионов записей, он состоит из песен и их исполнителей.

У меня есть

a track_id
an artist_id.

Есть 3 таблицы

tracks (track_id, title, artist_id),
artists(artist_id and artist_name) and
artist_term (artist_id and term).

Использование только один запрос, мне нужно посчитать количество треков, у исполнителей которых нет связанных терминов.

Для справки, схема БД выглядит следующим образом:

CREATE TABLE tracks (track_id text PRIMARY KEY, title text, release text, year int, duration real, artist_id text);
CREATE TABLE artists (artist_id text, artist_name text);
CREATE TABLE artist_term (artist_id text, term text, FOREIGN KEY(artist_id) 
REFERENCES artists(artist_id));

Как мне добраться до решения? пожалуйста помогите!

Ответы [ 3 ]

1 голос
/ 26 января 2020

Вы можете использовать not exists:

select count(*) cnt
from tracks t
where not exists (select 1 from artist_term at where at.artist_id = t.artist_id)

Что касается вопросов, вам не нужно вносить таблицу artists, поскольку artist_id доступен как в tracks, так и в artist_term таблицы.

Для производительности вам нужен индекс на tracks(artist_id) и еще один на artist_term(artist_id).

Анти-left join также выполнит работу:

select count(*) cnt
from tracks t
left join artist_term at on at.artist_id = t.artist_id
where at.artist_id is null
0 голосов
/ 26 января 2020

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

SELECT COUNT(track_id)
FROM tracks as t
WHERE EXISTS (
    SELECT *
    FROM artists AS a
    WHERE a.artist_id = t.artist_id
    AND NOT EXISTS(
        SELECT *
        FROM artist_term as at
        WHERE at.artist_id = a.artist_id
    )
)

Таким образом, этот запрос в основном говорит: подсчитать количество разных треков (помеченных их уникальными track_id), где есть исполнитель с таким же artist_id, где не существует artist_term, который относится к artist_id художника.

Надеюсь, это поможет!

0 голосов
/ 26 января 2020

Вы можете присоединиться к таблицам tracks и artists, а слева присоединиться к таблице artist_term, чтобы найти несравненные artist_id s:

select count(distinct t.track_id)
from tracks t
inner join artists a on a.artist_id = t.artist_id
left join artist_term at on at.artist_id = a.artist_id
where at.artist_id is null

Условие at.artist_id is null в * Предложение 1009 * вернет только несопоставленные строки, которые будут подсчитаны.

...