我似乎无法弄清楚为什么只有当john低于a时此查询才有效。
聊天表
**chatid** **username**
132 john
测试表
**chatid** **username**
132 john
132 a
查询
CREATE TEMPORARY TABLE tmp ( ids INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,id Int NOT NULL);
INSERT INTO tmp (id) VALUES (132);
SELECT i.id, IFNULL(COUNT(ta.chatid),0), count(l.chatid),IFNULL(x.username, '@')
FROM tmp i
inner JOIN chat ta ON ta.chatid = i.id
left JOIN test l ON ta.chatid = l.chatid
left JOIN chat x ON (x.chatid = l.chatid and x.username = l.username)
GROUP BY i.id
ORDER BY i.ids asc;
聊天测试表是一对多的关系。查询只能根据测试表的顺序正常工作。例如,如果john低于a,它将显示正确的john。但是,如果john高于a,则查询会导致null用户名不正确(仍应显示john)。
目标:我尝试只显示x.username,如果他在聊天和测试表中都存在,否则显示为null(@)。我需要这个工作而不会搞乱select语句中的计数
非常感谢任何帮助
答案 0 :(得分:1)
你是外连接x,所以对于某些记录,可能会填充x.username,对于某些记录,它可能为null。您按i.id
分组并选择x.username
。但是对于一个id,可以有许多用户名,甚至是NULL,如示例中所示。你没有告诉DBMS你想要哪一个(例如字母表中的最后一个用户名),所以DBMS任意选择一个。在你的情况下为NULL。运气不好,但是你把它留给了机会,所以不要抱怨; - )
我不知道你想要达到什么目标。您的示例太小,我无法准确理解查询应该执行的操作。但无论如何,在聚合时,告诉DBMS要选择哪个值。 IFNULL(MIN(x.username), '@')
可以在这里解决问题(但我无法判断查询是否完全符合您的要求)。
这就是你所追求的:计算测试中chatid的所有出现次数并仅在测试记录中存在时显示用户名?
select
c.chatid,
count(t.chatid),
case when max(t.username = c.username) then c.username else '@' end
from chat c
left join test t on t.chatid = c.chatid
where c.chatid in (select id from tmp)
group by c.chatid;