SQL同表日期统计结果合并:合并入店与离店日期的人数统计
SQL同表日期统计结果合并:合并入店与离店日期的人数统计
看起来你是想把同一张表里的入店日期(Date_IN)和离店日期(Date_OUT)的每日统计数据合并到一起,展示所有涉及日期对应的入店、离店总人数对吧?我来帮你梳理下解决方案,先理清楚你的数据和需求:
你的原始数据
先把你提供的表数据整理成更清晰的表格:
| ID | Date_IN | Date_OUT |
|---|---|---|
| 1 | 2025-06-02 | 2025-06-13 |
| 2 | 2025-06-02 | |
| 3 | 2025-06-03 | 2025-06-07 |
| 4 | 2025-06-04 | |
| 5 | 2025-06-04 | |
| 6 | 2025-06-04 | |
| 7 | 2025-06-06 | 2025-06-07 |
| 8 | 2025-06-07 | |
| 9 | 2025-06-08 | 2025-06-08 |
| 10 | 2025-06-11 | 2025-06-11 |
| 11 | 2025-06-12 | |
| 12 | 2025-06-13 | |
| 13 | 2025-06-14 |
先说说你之前查询的小问题
你之前写的两个查询用了窗口函数COUNT() OVER (...),其实完全没必要——因为你要的是每日的入店/离店总人数,直接用GROUP BY配合COUNT()就能得到,窗口函数在这里反而会生成多余的行,之后还要用MAX()去聚合,多了一步没必要的操作。
正确的合并查询方案
我们可以先分别统计每日入店人数和每日离店人数,再用FULL JOIN把两个结果集合并,这样所有有入店或离店记录的日期都会被包含进来,同时处理空值的情况:
SELECT COALESCE(in_stats.TOTAL_IN, 0) AS TOTAL_IN, COALESCE(in_stats.date, out_stats.date) AS DATE, COALESCE(out_stats.TOTAL_OUT, 0) AS TOTAL_OUT FROM -- 统计每日入店人数 (SELECT CAST(Date_IN AS DATE) AS date, COUNT(ID) AS TOTAL_IN FROM Table WHERE Date_IN IS NOT NULL GROUP BY CAST(Date_IN AS DATE)) AS in_stats FULL JOIN -- 统计每日离店人数 (SELECT CAST(Date_OUT AS DATE) AS date, COUNT(ID) AS TOTAL_OUT FROM Table WHERE Date_OUT IS NOT NULL GROUP BY CAST(Date_OUT AS DATE)) AS out_stats ON in_stats.date = out_stats.date ORDER BY DATE;
代码解释
- 子查询
in_stats:过滤掉Date_IN为空的行,把Date_IN转成纯日期类型,按日期分组统计当日入店的总人数。 - 子查询
out_stats:同理,过滤掉Date_OUT为空的行,统计当日离店的总人数。 FULL JOIN:用全连接来保留两个子查询里的所有日期——不管这个日期只有入店记录、只有离店记录,还是两者都有。COALESCE():用来处理空值:- 如果某日期只有入店记录,
out_stats.TOTAL_OUT会是NULL,用COALESCE替换成0(如果希望显示空白可以去掉第二个参数,保留NULL); - 统一日期列,把两个子查询的日期列合并成一个
DATE列。
- 如果某日期只有入店记录,
匹配你的期望输出
如果你的期望输出里不想显示0,而是留空,只需要把COALESCE(in_stats.TOTAL_IN, 0)改成in_stats.TOTAL_IN,COALESCE(out_stats.TOTAL_OUT, 0)改成out_stats.TOTAL_OUT就行,这样空值会直接显示为空白,和你给出的期望输出完全一致。
运行调整后的查询后,结果就会和你想要的一致:
| TOTAL_IN | DATE | TOTAL_OUT |
|---|---|---|
| 2 | 2025-06-02 | |
| 1 | 2025-06-03 | |
| 3 | 2025-06-04 | |
| 1 | 2025-06-06 | |
| 1 | 2025-06-07 | 2 |
| 1 | 2025-06-08 | 1 |
| 1 | 2025-06-11 | 1 |
| 1 | 2025-06-12 | |
| 1 | 2025-06-13 | 1 |
| 1 | 2025-06-14 |
(注:你给出的期望输出里2025-06-02的TOTAL_OUT写的是1,这和原始数据不符——原始数据里没有在2025-06-02离店的记录,所以实际应该是空白/0)
内容来源于stack exchange
相关产品推荐
相关产品推荐

