Перекрестное соединение 3 столбцов и необходимость устранения нулевых строк, если null при определенных условиях

#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. Спасибо! Это именно то, что мне было нужно.