首页 > 解决方案 > 交叉连接 3 列,如果在某些条件下为空,则需要消除空行

问题描述

好的,这有点难以解释,但我会在这里尽力而为。我在 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只投票过一次。小提琴的输出非常接近我想要的但我需要消除显示整个日期范围内所有空票的行 () 19-24。tick 32021-10-27ilocatticks 1 and 2user 12

换句话说,如果 auser从未对 a 投票,tick不想返回这些行。但是,如果 a至少在 auser上投票过一次,那么我想返回与所有日期对应的所有行(并在未投票的日子显示空票)。tickuser

我需要查看用户未投票的所有日期的原因是因为我正在执行稍后的查询以查找用户在他们投票的每个刻度上的条纹。您可以想象,如果我无法消除那些不必要的行,我尝试过的查询将产生非常大的结果。

标签: mysqljoingroup-bycross-join

解决方案


如果用户从未对勾号投票,我不想返回这些行。但是,如果用户至少在一个刻度上投票了一次,那么我想返回对应于所有日期的所有行

You should change the CROSS join to an INNER join:

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;

See the demo.


推荐阅读