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。

相关推荐
九章-11 小时前
一库平替,融合致胜:国产数据库的“统型”范式革命
数据库·融合数据库
2401_8384725111 小时前
使用Scikit-learn构建你的第一个机器学习模型
jvm·数据库·python
u01092727111 小时前
使用Python进行网络设备自动配置
jvm·数据库·python
wengqidaifeng11 小时前
数据结构---顺序表的奥秘(下)
c语言·数据结构·数据库
what丶k11 小时前
SpringBoot3 配置文件使用全解析:从基础到实战,解锁灵活配置新姿势
java·数据库·spring boot·spring·spring cloud
Code blocks11 小时前
kingbase数据库集成Postgis扩展
数据库·后端
天下·第二12 小时前
达梦数据库适配
android·数据库·adb
Dxy123931021612 小时前
MySQL INSERT ... ON DUPLICATE KEY UPDATE 批量更新详解
数据库·mysql
定偶12 小时前
MySQL知识点
android·数据结构·数据库·mysql
醒过来摸鱼12 小时前
Redis 服务器线程与事件循环解析
服务器·数据库·redis