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。

相关推荐
稷下元歌12 小时前
七天学会plc 加机器视觉完整笔记:S7-1200 数据类型、存储区与寻址方式(I/Q/M/DB 详解)。
网络·数据库·笔记
潮起鲸落入海12 小时前
mysql 5.x源码安装
数据库·mysql
睡不醒男孩03082313 小时前
第一篇:多云与多模态时代的企业级数据库云管理平台(DBaaS)选型指南
数据库·clup·中启乘数
小二·13 小时前
向量数据库实战
数据库
炘爚13 小时前
Phase 5:MySQL 连接池
数据库·mysql
j_xxx404_14 小时前
MySQL库操作硬核解析:字符集、校验规则、大小写比较、备份恢复与连接排查
运维·服务器·数据库·人工智能·mysql·ai·oracle
minji...14 小时前
MySQL数据库 (五) MySQL表的约束(上),非空约束,默认值约束,零填充约束,主键约束,符合主键
数据库·mysql·表的约束·主键约束·非空约束·复合主键·零填充约束
拾贰_C14 小时前
【python | installation 】python 安装 | Windows | 命令使用
linux·数据库·ubuntu
贺今宵15 小时前
Vue 3 + Capacitor 使用jeep-sqlite,web端使用本地sqlite数据库
前端·数据库·vue.js·sqlite·web
列星随旋15 小时前
MySQL面经整理
数据库·mysql