Помогите с sql запросом one-to-many

216
26 марта 2017, 06:16

Есть таблица support_tickets и таблица ticket messages

связазь one-to-many. Нужен запрос который будет искать те тикеты, у которых не существует ticket_messages

Пока есть такой вариант

SELECT * FROM support_tickets where id not in (SELECT distinct ticket_id from ticket_message)

Есть ли альтернативные варианты, которые будет работать быстрее?

Answer 1
SELECT DISTINCT st.* 
FROM support_tickets st
WHERE NOT EXISTS (SELECT id 
                  FROM ticket_message tm
                  WHERE st.id = tm.ticket_id
);

NOT EXIST - возвращает значение 1 (TRUE), если результат подзапроса не содержит ни одной строки в подзапросе, и значение 0 (FALSE), если подзапрос что-то содержит

А вот быстрее ли такой запрос, чем ваш с IN может подсказать разве что EXPLAIN

Answer 2

Можно еще попробовать так:

SELECT st.* 
FROM support_tickets st
LEFT JOIN ticket_message tm ON tm.ticket_id = st.ticket_id
WHERE tm.ticket_id IS NULL

Выбор варианта - на основе анализа плана выполнения.

UPDATE

SQL сервер для вашего запроса и варианта Олега строит идентичный план выполнения. Для моего варианта план немного отличается - использует SORT вместо DISTINCT SORT и LEFT JOIN вместо RIGHT ANTI SEMI JOIN, что приводит к изменению стоимости с 0.085 до 0.087 - т.е. чуть хуже, но это на моих тестовых данных; на других данных результат может быть иной.

UPDATE 2

И действительно - в первом случае у меня в таблице ticket_message было много меньше записей, чем в support_ticket. В другом случае, когда в таблице ticket_message записей много больше (это более реалистичный вариант, не правда ли?), мой запрос дает практически такой же результат, что запрос Олега (стоимость 0.14 и 0.15, соответственно), а ваш - почти вдвое хуже (0.25).

READ ALSO
Как извлечь версию .exe файла [требует правки]

Как извлечь версию .exe файла [требует правки]

В проекте производится запуск внешнего приложенияНеобходимо проверить, та ли версия внешней prog

288
Удалить из строки все слова не являющиеся идентификаторами. C++

Удалить из строки все слова не являющиеся идентификаторами. C++

Как сравнивать вводимые слова со всеми ключевыми?

361
Коррупция, задача на жадный алгоритм

Коррупция, задача на жадный алгоритм

Помогите мне, пожалуйста, решить эту задачу, а также объяснить, как получается ответ в первом тесте

279
Найти количество инверсий [требует правки]

Найти количество инверсий [требует правки]

Найдите количество инверсий в лексикографически K-ой перестановке чисел от 1 до N

519