SQLite удаляет дубликаты из таблицы с несколькими строками с одинаковым первичным ключом - PullRequest
0 голосов
/ 23 июня 2019

Мой вопрос - перечислить всех режиссеров, которые сняли 10 или более фильмов, в порядке убывания количества фильмов, которые они сняли. Верните имена режиссеров и количество фильмов, каждый из которых был снят

У меня есть две таблицы, одна из которых является таблицей Director, в которой есть столбцы ID (первичный ключ), MID, PID. а другой - это таблица Person с столбцами PID (первичный ключ), Name, Gender.

Следующий мой запрос

SELECT Name, COUNT(*) movies_directed
FROM Director
LEFT JOIN Person USING(PID)
GROUP BY PID
HAVING movies_directed >= 10
ORDER BY movies_directed DESC;

Но проблема в том, что в Person есть несколько строк с одинаковым PID.

Вот пример данных

Когда я выполняю запрос

SELECT * FROM Person WHERE Name LIKE '%Andy Serkis%';

результат

index        PID          Name           Gender
4        'nm0785227'     **' Andy Serkis'**  'Male'
36821    'nm0785227'     'Andy Serkis'   'Male'

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

Ответы [ 3 ]

0 голосов
/ 23 июня 2019

Это должно сработать.

SELECT Name, COUNT(*) movies_directed
FROM Director
Where exists
(SELECT 1 FROM  Person 
WHERE Director.PID = Person.PID)
GROUP BY PID
HAVING movies_directed >= 10
ORDER BY movies_directed DESC;

Но в идеале вам нужно обратиться к отдельной таблице с уникальным идентификатором лица и использовать предложение объединения.

0 голосов
/ 23 июня 2019

Сначала выполните эту DELETE инструкцию:

delete from Person 
where exists (
  select 1 from Person p 
  where p.pid = Person.pid and p.name <> Person.name and p.rowid < Person.rowid
);

, которая удаляет дубликаты PID с и сохраняет только одну с более низким RowId.Затем выполните команду UPDATE:

update Person
set name = trim(name);

, чтобы исправить любые имена, содержащие пробелы в конце или начале.Если есть и другие несоответствия, вы можете выполнить аналогичные операторы UPDATE.Тогда ваш код должен работать, если вы используете правильные псевдонимы для таблиц и квалифицируете столбцы с ними.

0 голосов
/ 23 июня 2019

Но здесь проблема в том, что в Person есть несколько строк с одинаковым PID.

Это не имеет смысла.Предположительно, PID является первичным ключом для таблицы Person.Это будет означать, что в Person есть только одна строка на значение.В Director может быть несколько строк - потому что человек может снять несколько фильмов.

Я думаю, что ваш запрос вернул бы правильные результаты.Тем не менее, это не правильно сформулировано.

Было бы лучше использовать внутреннее объединение, потому что вы рассматриваете только тех людей, которые сняли хотя бы один фильм (ну, по крайней мере, 10).Итак:

SELECT p.Name, COUNT(*) as movies_directed
FROM Person p JOIN
     Director d
     USING (PID)
GROUP BY PID, p.Name
HAVING movies_directed >= 10
ORDER BY movies_directed DESC;

Примечания:

  • Когда вы обращаетесь к нескольким таблицам, вы должны указать все имена столбцов.Единственным исключением являются столбцы в предложении USING.
  • Псевдонимы таблиц облегчают написание и чтение запроса.
  • В вашей версии у вас есть COUNT(*).Это обычно не подходит с LEFT JOIN.Обычно вы хотите подсчитать совпадения в таблице second .
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...