【问题标题】:How both asterisked lines are correct given the SQL statement给定 SQL 语句,两个带星号的行如何正确
【发布时间】:2022-07-05 23:28:18
【问题描述】:

一个新的社交网站有以下数据表:

用户

id name sex
1 Ann null
2 Steve m
3 Mary f
4 Brenda f

朋友

user1 user2
1 2
1 3
2 3

选择将由以下 SQL 查询返回的数据:

  SELECT users.name, 
         COUNT(*) as count 
    FROM users LEFT JOIN 
         friends ON users.id = friends.user1 OR users.id = friends.user2
   WHERE users.sex = 'f'
GROUP BY users.id, 
         users.name;

输出

name count
Ann 1
Ann 2
Steve 1
Steve 2
Mary 1
Mary 2 **
Brenda 0
Brenda 1 **

带星号的部分是正确答案,但我不太明白为什么 (Brenda, 1) 在 (Mary, 2) 也是正确答案时会在这里成为答案。

【问题讨论】:

  • "星号部分是正确答案" - 请问最初的问题是什么?
  • 去掉计数和分组,在SELECT子句中包含所有列。检查该结果集。然后,您应该了解应用 GROUP BY 时发生的情况。提示 - COUNT(*) 在此查询中永远不会返回 0。
  • @DmitryBychenko 我知道他们是正确的,但我只是不确定为什么 Brenda,1 是正确的。我以为答案只是玛丽,2。我的理由是 Brenda 的 id 没有出现在friends 表中。是不是因为这里专门使用了左连接?
  • 为什么布伦达计数为 1?看到不在朋友表中
  • @Damien_The_Unbeliever 我想我明白了。所以我们在这里得到 brenda,1 的原因是 group by 子句的功能。即使在朋友表中添加一条记录,以便布伦达有一个与她的用户关联的朋友,输出仍然是 brenda,1。只有在至少有 2 个条目时才会增加到 brenda,2。

标签: sql select


【解决方案1】:

为了解决这个问题并避免Brenda = 1的情况,你可以:

  • 通过将 (user1, user2) 夫妇与 (user2, user1) 夫妇放在一起,生成一个“friends”表
  • 通过匹配“users.id”“cte.user1
  • 将此表与您的“users”表连接起来
  • 与“cte.user1”字段上的COUNT 函数聚合,按用户名分组。
WITH cte AS (
    SELECT user1, user2 FROM friends
    UNION ALL 
    SELECT user2, user1 FROM friends
)
SELECT users.name,
       COUNT(cte.user1) AS cnt
FROM      users
LEFT JOIN cte
       ON users.id = cte.user1
GROUP BY users.name

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-31
    • 2011-02-25
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    相关资源
    最近更新 更多