SQL核心(1)

1:注意点

1.1:描述:

用户表用8人,但是订单表只有7个人的订单,在统计每个用户的订单数量的时候,要注意count(*),count(列名),null值的处理

1.2:原有SQL:

sql 复制代码
select a.user_id,count(*) from dim_users a left join fact_orders b 
on a.user_id = b.user_id 
group by a.user_id

1.3:发现问题(结果)

结果是,一个用户没有订单时,根据下面的SQL,没有订单的用户 获取得到的订单总数 = 1;

1.4:分析和解决问题

1:问题描述

select a.user_id,count(*) from dim_users a left join fact_orders b on a.user_id = b.user_id group by a.user_id ; 为什么表dim_users有8个用户,表fact_orders只有7个用户的订单;但是最后没有订单的用户=1;
核心:count(*) 和count(列名)

COUNT(*) 统计的是行数(是否存在这行)。
COUNT(列名) 统计的是该列中非 NULL 值的个数。

1.2:分析:

关键点在于,由于是 LEFT JOIN主表 dim_users 的所有记录都会被保留 。对于没有匹配订单的用户U8,来自 fact_orders 表的所有字段都会用 NULL 填充。

接下来,GROUP BY a.user_id 对这个结果集进行分组,然后 COUNT(*) 统计每个分组内的行数

  • 对于用户 U1 到 U7:他们的分组里都至少有一条与订单匹配的记录,COUNT(*) 的结果就是他们的订单数量(可能是1,也可能是多条)。

  • 对于用户 U8:他的分组里只有 1 行 (就是那条由 LEFT JOIN 生成的、订单字段全为 NULL 的行)。因此,COUNT(*) 的结果是 1

1.3:结论和建议

✅ 结论与建议

所以,你的查询结果准确地显示了:8个用户都出现在结果中,其中7个有订单的用户显示了订单数,那1个没有订单的用户计数为1。

如果你想更直观地看到"没有订单的用户数为0",可以将 COUNT(*) 改为 COUNT(b.user_id)COUNT(b.order_id)。这是因为 COUNT(列名) 会忽略该列的 NULL

SELECT

a.user_id,

COUNT(*) AS total_rows, -- 会为无订单用户返回1

COUNT(b.user_id) AS order_count -- 会为无订单用户返回0

FROM dim_users a

LEFT JOIN fact_orders b ON a.user_id = b.user_id

GROUP BY a.user_id;

运行上面的修改后查询,你就能清楚地看到 COUNT(*)COUNT(特定列) 在处理 NULL 值时的核心区别了。

如果你还有其他关于 SQL 逻辑的疑问,随时可以提出。

1.5:区分count(*)和count(列名)

  1. COUNT(*) 是"元组计数"

    • 它关心的是"行"这个容器本身 。只要这行数据存在,无论其内部字段是值还是 NULL,它都客观占据一行。因此,它必然包含所有行。

    • 在上面的 LEFT JOIN 例子中,即使用户U8对应的订单字段全是 NULL,但这一行数据是确定存在的 ,所以 COUNT(*) 会将其计入。

  2. COUNT(列名) 是"值计数"

    • 它关心的是某个特定"值"是否有效 。在 SQL 中,NULL 表示"未知"、"缺失"或"不适用",不是一个有效的"值"。因此,在统计时,所有 NULL 都会被排除在外。

    • LEFT JOIN 的例子中,对 COUNT(b.user_id) 来说,用户U8对应的 b.user_idNULL,所以被忽略,结果为0。

相关推荐
这个DBA有点耶1 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
DBA_G1 天前
从地面到云霄:GBase数据库在民航三大场景的落地实践
数据库
自由能燃气设备1 天前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南
大数据·数据库·人工智能
科创致远1 天前
科创致远 ESOP 系统核心效能与实战价值展示
大数据·数据库·人工智能·精益工程
漂着的圆木1 天前
Agent 功能参与度:Copilot 怎么算
sql·数据分析·agent·githubcopilot·度量
2601_962218611 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法
张洛闻Eren1 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
于平安1 天前
MySQL-触发器
数据库·mysql
白远山1 天前
上海24小时自助健身房解决方案实战指南与经验分享
java·数据库·架构·需求分析
Omics Pro1 天前
斯坦福Nature+Science|广义虚拟细胞基础大模型
数据库·人工智能·算法·机器学习·自然语言处理