何时在包含 JOIN 和聚合的 SQL 查询中使用 *?
Posted
技术标签:
【中文标题】何时在包含 JOIN 和聚合的 SQL 查询中使用 *?【英文标题】:When to Use * in SQL Query Containing JOINs & Aggregations? 【发布时间】:2020-08-10 15:07:26 【问题描述】:问题
Web_events
表包含id
,..., channel
,account_id
accounts
表包含id
, ..., sales_rep_id
sales_reps
表包含id
、name
给定上述表,编写一个 SQL 查询来确定特定 channel
在 web_events
表中用于 sales_reps
中每个名称的次数。您的最终表格应该包含三列 - sales_reps
、channel
的名称和出现次数。首先对出现次数最多的表格进行排序。
回答
SELECT s.name, w.channel, COUNT(*) num_events
FROM accounts a
JOIN web_events w
ON a.id = w.account_id
JOIN sales_reps s
ON s.id = a.sales_rep_id
GROUP BY s.name, w.channel
ORDER BY num_events DESC;
COUNT(*)
让我很困惑。我不明白 SQL 是如何计算出COUNT(*)
是COUNT(w.channel)
。谁能澄清一下?
【问题讨论】:
像count()
这样的聚合门函数会为您定义的每个组返回结果。
COUNT(*)
表示“计数行”,即组合在一起的行数。与COUNT(w.channel)
相同,但前提是w.channel
不能为NULL
。
基于Group By
子句。只是为了补充一点,在您的情况下,count(*)
可能与count(w.channel)
不同。您在组中也有s.name
,这意味着count(*)
将根据s.name
和w.channel
的组合给出计数
【参考方案1】:
我不明白 SQL 是如何计算出 COUNT(*) 是 COUNT(w.channel)
COUNT()
是一个聚合函数,用于计算匹配条件的行数。事实上,一般COUNT(<expression>)
(或特别是COUNT(column)
)计算表达式(或列)不是NULL
的行数。
一般来说,以下完全做同样的事情:
COUNT(*)
COUNT(1)
COUNT(<primary key used on inner join>)
一般来说,我更喜欢COUNT(*)
,因为这是SQL 标准。我可以接受COUNT(1)
承认COUNT(*)
只是功能膨胀。但是,我认为没有理由使用第三个版本,因为它只是需要额外的输入。
除此之外,我发现新用户经常对这两种结构感到困惑:
COUNT(w.channel)
COUNT(DISTINCT w.channel)
学习 SQL 的人通常认为第一个确实是第二个。出于这个原因,我建议坚持使用更简单的行数计数方法。然后,当您真的想产生计算唯一值的开销时使用COUNT(DISTINCT)
(COUNT(DISTINCT)
比COUNT()
更昂贵)。
【讨论】:
以上是关于何时在包含 JOIN 和聚合的 SQL 查询中使用 *?的主要内容,如果未能解决你的问题,请参考以下文章
T-SQL GROUP BY 也使用 JOIN、聚合和外部引用错误
clickhouse,数据查询与写入优化,分布式子查询优化,外部聚合/排序优化,基于JOIN引擎的优化,SQL优化案例,物化视图提速,查询优化常用经验法则,选择和主键不一样的排序键,数据入库优化(代码