多层Left Join筛选后如何保留无关联账户并统计唯一(date,shift)记录?
解决方案:获取所有账户并统计符合条件的唯一(date,shift)记录数(含无关联记录的账户)
我来帮你搞定这个问题——你当前的查询之所以过滤掉了无关联记录的账户,核心原因是把projektwochen_id=8的条件放在了WHERE子句里,这会让左连接退化成内连接,直接排除掉没有匹配projektkurse记录的账户。
下面是修正后的完整SQL查询:
SELECT a.id, a.vorname, a.nachname, COUNT(DISTINCT z.date, z.shift) AS unique_shift_count FROM accounts a LEFT JOIN projektkurse pk ON a.id = pk.accounts_id AND pk.projektwochen_id = 8 -- 把条件移到JOIN的ON子句里 LEFT JOIN projektkurs_einzel pke ON pk.id = pke.projektkurse_id LEFT JOIN projektkurs_einzel_zeiten z ON pke.id = z.projektkurs_einzel_id GROUP BY a.id, a.vorname, a.nachname;
关键修改点说明:
条件位置调整:
把pk.projektwochen_id = 8从WHERE移到LEFT JOIN projektkurse的ON子句中,这样既会只关联符合条件的projektkurse记录,又能保留所有accounts表中的账户(哪怕没有匹配的projektkurse记录)。统计逻辑优化:
使用COUNT(DISTINCT z.date, z.shift)来统计唯一的(date,shift)组合:- 如果账户有符合条件的zeit记录,会自动去重计数;
- 如果账户没有任何关联的zeit记录,
z.date和z.shift都会是NULL,COUNT函数会返回0,正好满足你的需求。
分组规则:
按账户的唯一标识(id、vorname、nachname)分组,确保每个账户只返回一行统计结果。
兼容旧版数据库的小技巧:
如果你的数据库不支持COUNT(DISTINCT 多列)(比如部分旧版本MySQL),可以用拼接字符串的方式替代:
COUNT(DISTINCT CONCAT(z.date, '###', z.shift)) AS unique_shift_count
注意选择一个不会出现在date或shift中的分隔符(比如###),避免拼接后出现重复的假阳性。
内容的提问来源于stack exchange,提问作者Benjamin Frost
相关产品推荐
相关产品推荐

