#mysql #sql
#mysql #sql
Вопрос:
Вот мой текущий запрос:
SELECT q.type,
q.author_id author,
q.deleted,
q.deleter_id,
COUNT(DISTINCT a.id) answers_num,
COUNT(DISTINCT v.id) votes_num,
FROM qanda q
LEFT JOIN qanda a ON q.id = a.related
LEFT JOIN votes v on q.id = v.post_id
WHERE q.id = ?
Это работает хорошо. Просто мне нужно добавить еще одну вещь (которая возвращает логическое значение by EXISTS
) в SELECT
инструкции. Это:
EXISTS (SELECT a.id, sum(vot.value) total_votes
FROM qanda q
LEFT JOIN qanda a on q.id = a.related
LEFT JOIN votes vot ON a.id = vot.post_id
WHERE q.type = 0 -- this is a question
AND a.related = 1315 -- getting answers
GROUP BY a.id
HAVING total_votes
ORDER BY total_votes DESC
LIMIT1
) as HasAUpvotedAnswer
Хорошо, это тоже хорошо работает. Но я беспокоюсь о производительности. Как вы можете видеть, JOIN
s этих двух запросов выше (которые будут объединены окончательно) похожи. Как сделать их более оптимальными?
Другими словами, как я могу объединить эти два вышеуказанных запроса в наиболее оптимальном случае?
Комментарии:
1. Не могли бы вы поделиться парой строк из вашей базы данных с репрезентативным примером того, что вы пытаетесь сделать, и ожидаемым результатом?
2. @MarcinJ Концептуально я пытаюсь сделать «вы не можете удалить свой вопрос, потому что в нем есть один ответ, за который проголосовали, или два ответа, или и т. Д.» Для веб-сайта вопросов и ответов, подобного ЭТОМУ.
3. имеют ли несколько строк, которые вы получаете через ЛЕВОЕ СОЕДИНЕНИЕ, одинаковые данные? если это так, вы могли бы в принципе РАЗДЕЛИТЬ свой результирующий набор. если нет, я бы посмотрел на условия объединения, если вы можете добавить дополнительные условия, чтобы сделать их отличными
4. @stack В настоящее время я не знаю, с какой проблемой вы столкнулись, поэтому важно поделиться парой строк, которые представляют то, что вы пытаетесь сделать. В вашем подзапросе EXISTS вы жестко запрограммировали некоторые идентификаторы, поэтому мы не можем выяснить, каковы условия объединения для связанного подзапроса. Вставьте пару строк из
qanda
иvotes
, а затем строки, которые вы ожидаете получить в результате вашего запроса. Люди не любят гадать, что вы пытаетесь сделать, как расположены ваши данные и т. Д.
Ответ №1:
Судя по вашему коду, y может использовать один запрос, используя условное выражение для суммы
SELECT q.type,
q.author_id author,
q.deleted,
q.deleter_id,
COUNT(DISTINCT a.id) answers_num,
COUNT(DISTINCT v.id) votes_num,
IF (SUM(
CASE WHEN q.type = 0 AND a.related = 1315
THEN v.value else 0 END) > 0,1,0)
HasAUpvotedAnswer
FROM qanda q
LEFT JOIN qanda a ON q.id = a.related
LEFT JOIN votes v on q.id = v.post_id
WHERE q.id = ?
Комментарии:
1. 1) Круглые скобки в конце
HasAUpvotedAnswer
являются избыточными. 2) Он выдает:Unknown column 'v.votes' in 'field list'
2. ответ обновлен .. v.значение, а не v.голоса .. голоса — это таблица с псевдонимом v
3.В настоящее время значение
HasAUpvotedAnswer
равно6
(для моего реального набора данных). Ожидалось, что я буду логическим значением (либо0
или1
, например, чтоEXISTS
возвращает)4. добавлено значение if sum> 0 для 1 или 0
5. Ну, видимо, это работает ..! Но я предполагаю, что логика неверна. Поскольку мы даже не учитываем значение голосов в ответах. Поскольку мы не объединяем таблицу ответов (
qanda
asa
) сvotes
таблицей.