#mysql #join #group-by #cross-join
Вопрос:
Хорошо, это довольно сложно объяснить, но я сделаю все возможное. Я пересекаю объединение в 3 столбцах и мне нужно исключить определенные строки, чтобы результаты не были чрезмерно большими. Я думаю, что это лучше всего объяснить скрипкой.
У меня есть две таблицы:
ticks(dait DATE, tick INT);
votes(dayt DATE, tick INT, user INT, vote INT);
И мне нужно перекрестно соединить их dait, tick, user
. Вот где полезна скрипка.
https://www.db-fiddle.com/f/9phZ7EpRUS4FNRBZRdSYZa/29
И вот запрос, который я пробовал, который дал мне самый близкий:
SELECT x.user, ticks.tick, dait, vote, ROW_NUMBER() OVER (ORDER BY x.user, ticks.tick,
dait) AS ilocat
FROM ticks
CROSS JOIN (SELECT DISTINCT dayt, user, tick FROM votes) x
LEFT JOIN votes
ON votes.dayt = ticks.dait AND votes.tick = ticks.tick AND x.user = votes.user
GROUP BY dait, ticks.tick, x.user
ORDER BY x.user, ticks.tick, dait;
Вы можете видеть user 12
, что проголосовал только один раз на tick 3
on 2021-10-27
. Вывод скрипки очень близок к тому, что я хочу, НО мне нужно исключить строки ( ilocat
) 19-24, которые показывают все нулевые голоса за ticks 1 and 2
из user 12
всего диапазона дат.
Другими словами, если a user
никогда не голосовал за a tick
, я не хочу возвращать эти строки. НО, если a user
проголосовал хотя бы один раз за a tick
, тогда я хочу вернуть все строки, соответствующие всем датам (и показать нулевые голоса в те дни user
, когда они не голосовали).
Причина, по которой мне нужно видеть все даты, за которые пользователь не голосовал, заключается в том, что я выполняю более поздние запросы, чтобы найти полосы пользователя по каждому тику, за который они проголосовали. Как вы можете себе представить, запрос, который я пробовал, даст очень большие результаты, если я не смогу удалить эти ненужные строки.
Комментарии:
1. пожалуйста, проверьте ссылку на скрипку db, не относящуюся к вопросу.
2. И мне нужно перекрестно соединить их
dait, tick, user
. Фраза не имеет смысла. Перекрестное соединение не имеет никаких условий, оно объединяет все возможные пары безоговорочно.3. Скрипка была обновлена. Мои извинения.
4. Приятно видеть, что кто-то уже ответил на это за вас! 🙂 Удачного вам!
Ответ №1:
если пользователь никогда не голосовал за галочку, я не хочу возвращать эти строки. НО, если пользователь проголосовал хотя бы один раз на галочке, я хочу вернуть все строки, соответствующие всем датам
Вы должны изменить CROSS
соединение на INNER
соединение:
SELECT x.user, t.tick, t.dait, v.vote,
ROW_NUMBER() OVER (ORDER BY x.user, t.tick, dait) AS ilocat
FROM ticks t
INNER JOIN (SELECT DISTINCT dayt, user, tick FROM votes) x
ON t.tick = x.tick
LEFT JOIN votes v
ON v.dayt = t.dait AND v.tick = t.tick AND x.user = v.user
GROUP BY dait, t.tick, x.user
ORDER BY x.user, t.tick, t.dait;
Смотрите демонстрацию.
Комментарии:
1. Спасибо! Это именно то, что мне было нужно.