【问题标题】:Odd Behavior From Query查询中的奇怪行为
【发布时间】:2015-12-15 15:35:54
【问题描述】:

我似乎无法弄清楚为什么这个查询只有在 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 则查询结果为不正确的空用户名(仍应显示 john)。

目标:我试图仅当 x.username 同时存在于聊天和测试表中时才显示他,否则显示 null(@)。我需要它在不弄乱 select 语句中的计数的情况下工作

【问题讨论】:

  • tsql 和 MySQL 都有???
  • @jarlh 语法上的唯一区别是临时表,它与所讨论的查询部分无关。所以我认为任何有 tsql 知识的人也可以提供帮助?
  • 直到解决方案不是 tsql。你不在 msft 上

标签: mysql sql tsql


【解决方案1】:

你外部连接 x,所以对于某些记录,x.username 可能会被填充,而对于某些记录,它可能是空的。您按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;

【讨论】:

  • 我怎么能不听天由命呢?由于它是一对多的关系,如果测试中有 10 个不同的用户名以任何顺序使用相同的 ID,我该如何尝试输出 john?如果他是第一个用户名,min 只会输出 john?
  • 我添加了一个可能满足您需求的查询。不过,我并不完全确定它确实如此,因为我在这里猜测你的意图。
  • 成功了!您能帮我了解一下 max 在您的查询中做了什么吗?
  • 我在这里使用 MySQL 布尔逻辑。对于 t.username = c.username 匹配的每个记录对,此表达式为 true = 1,对于每个其他名称,它为 false = 0。因此,如果至少一个记录对具有匹配的名称,MAX(t.username = c.username) 为 1 = true。在这种情况下,我显示c.username(这对于 c.chatid 来说是唯一的,所以我在这里不需要像 MIN(c.username) 这样的聚合函数)。否则我显示'@'。希望这可以澄清它。
猜你喜欢
  • 2010-10-24
  • 2016-02-24
  • 2010-11-26
  • 2012-09-24
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多