MYSQL возвращает список идентификаторов строк, которых нет в других таблицах базы данных - PullRequest
0 голосов
/ 04 февраля 2019

Я работаю над объединением старой базы данных в новую.В новой базе данных у меня есть четыре таблицы базы данных: 'task_clone', 'potential_task', 'task' и 'task_archive'.

'task_clone' содержит все записи базы данных типа задача, импортированные из более старой базы данных, и я пытаюсь распределить эти записи поостальные три таблицы в новой базе данных.'task_clone', следовательно, временная таблица.

'task_clone' содержит 649 записей.Структура данных не очень легко отображается в новую базу данных, и после копирования строк из 'task_clone' общая сумма записей трех других таблиц составляет 566, что означает, что в 'task_clone' есть 83 записи, которые еще не былисопоставлены с новой структурой.

Я пытаюсь запросить 'task_clone', чтобы выяснить, какие записи находятся в трех других таблицах, которых нет в 'task_clone'.

Все три таблицы содержат столбец 'task_id', который является уникальным идентификатором для каждой записи задачи.Поэтому я должен иметь возможность запрашивать базу данных и получать все столбцы 'task_id' в 'task_clone', возвращая значения, которые не совпадают с значениями в других трех таблицах.

Я знаю, что это возможно в одном запросе, но я не могу понять, что синтаксис правильный.Куда я иду не так и как это должно быть написано?Сначала я попытался:

SELECT task_clone.task_id 
FROM task_clone 
WHERE 
    task_clone.task_id != potential_task.task_id 
    AND task_clone.task_id != task.task_id 
    AND task_clone.task_id != task_archive.task_id;

Я также рассмотрел некоторые другие подходы к этому с двумя таблицами (то есть, возвращая значения из одной, которых не было в другой), но я не смог найти пример, который мог быперевести аккуратно в решение, которое будет работать для более чем двух таблиц без получения сообщений об ошибках.Спасибо за прочтение.

ПРИМЕЧАНИЕ. В ответ на это отметили, как дубликат: Этот вопрос не является дубликатом тех предыдущих вопросов, которые касаются конкретно двух таблиц, поскольку мой вопрос специально касается работы с четырьмя таблицами.Решение, представленное в цитируемом вопросе, хотя и с использованием примерно одинакового синтаксиса, не обеспечивает решение вопроса о 4 таблицах.Кроме того, в своем вопросе я четко заявляю, что посмотрел предыдущие ответы в стеке, которые касаются двух таблиц, и я не смог перевести их в четыре без получения сообщений об ошибках.

Ответы [ 3 ]

0 голосов
/ 04 февраля 2019

Я бы использовал NOT EXISTS:

SELECT tc.task_id
FROM task_clone tc
WHERE NOT EXiSTS (SELECT 1 FROM potential_task pt WHERE pt.task_id = tc.task_id) AND
      NOT EXiSTS (SELECT 1 FROM task t WHERE t.task_id = tc.task_id) AND
      NOT EXiSTS (SELECT 1 FROM task_archive ta WHERE ta.task_id = tc.task_id) ;

Я бы предпочел NOT EXISTS вместо NOT IN с подзапросами, потому что последний не обрабатывает NULL с интуитивно понятным образом.Если any task_id в любой из таблиц равно NULL, то внешний запрос не будет возвращать строки вообще.Это согласуется с тем, что NULL означает в SQL, но это не интуитивно понятно.

NOT EXISTS обрабатывает NULL с, как и следовало ожидать - они не совпадают в данной строке, но онине влияет на результаты в других строках.

0 голосов
/ 04 февраля 2019

Учитывая, что task_id является первичным ключом во всех таблицах, подход LEFT JOIN представляется более эффективным и лаконичным:

SELECT tc.*
FROM 
    task_clone tc
    LEFT JOIN potential_task pt ON pt.task_id = tc.task_id
    LEFT JOIN task t ON t.task_id = tc.task_id
    LEFT JOIN task_archive ta ON ta.task_id = tc.task_id
WHERE
    pt.task_id     IS NULL 
    AND t.task_id  IS NULL 
    AND ta.task_id IS NULL 
0 голосов
/ 04 февраля 2019

Не могли бы вы использовать NOT IN?

 SELECT task_clone.task_id FROM task_clone 
 WHERE task_clone.task_id NOT IN  (SELECT task_id from potential_task)
 AND task_clone.task_id NOT IN  (SELECT task_id from task)
 AND task_clone.task_id NOT IN  (SELECT task_id from task_archive)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...