You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过SQL查找日志表中每日未记录的用户-日期组合

找出日志表中缺失的日期-用户组合

我有一张每日追加数据的日志表table1,需要找出column3(用户)与column1(日期)中未被记录的组合。

原表数据

column1column2column3
2022-07-14274,5markus
2022-07-14251,2tess
2022-07-14162,6mike
2022-07-15286,9markus
2022-07-15254,8tess
2022-07-16289,1markus
2022-07-17295,2markus
2022-07-17260,0tess
2022-07-17182,3mike

期望输出

column1column3
2022-07-15mike
2022-07-16tess
2022-07-16mike

解决方案

核心思路是先生成所有日期-用户的可能组合,再筛选出原表中不存在的组合。

通用SQL写法

-- 生成所有日期和用户的笛卡尔积
WITH all_combinations AS (
    SELECT DISTINCT t1.column1, t2.column3
    FROM table1 t1
    CROSS JOIN table1 t2
),
-- 筛选出原表中已存在的组合
existing_combinations AS (
    SELECT DISTINCT column1, column3
    FROM table1
)
-- 找出不在已存在组合中的记录
SELECT ac.column1, ac.column3
FROM all_combinations ac
LEFT JOIN existing_combinations ec 
    ON ac.column1 = ec.column1 
    AND ac.column3 = ec.column3
WHERE ec.column1 IS NULL
ORDER BY ac.column1, ac.column3;

优化写法(针对日期序列完整场景)

如果需要确保覆盖原表中所有日期区间(包括原表可能遗漏的日期),可以用数据库自带的日期生成函数生成完整日期序列,再和所有用户做笛卡尔积:

PostgreSQL 示例

WITH all_dates AS (
    SELECT generate_series(
        (SELECT MIN(column1) FROM table1),
        (SELECT MAX(column1) FROM table1),
        INTERVAL '1 day'
    )::DATE AS column1
),
all_users AS (
    SELECT DISTINCT column3 FROM table1
),
all_combinations AS (
    SELECT ad.column1, au.column3
    FROM all_dates ad
    CROSS JOIN all_users au
)
SELECT ac.column1, ac.column3
FROM all_combinations ac
LEFT JOIN table1 t 
    ON ac.column1 = t.column1 
    AND ac.column3 = t.column3
WHERE t.column1 IS NULL
ORDER BY ac.column1, ac.column3;

MySQL 8.0+ 示例

WITH RECURSIVE all_dates AS (
    SELECT MIN(column1) AS column1 FROM table1
    UNION ALL
    SELECT DATE_ADD(column1, INTERVAL 1 DAY)
    FROM all_dates
    WHERE column1 < (SELECT MAX(column1) FROM table1)
),
all_users AS (
    SELECT DISTINCT column3 FROM table1
),
all_combinations AS (
    SELECT ad.column1, au.column3
    FROM all_dates ad
    CROSS JOIN all_users au
)
SELECT ac.column1, ac.column3
FROM all_combinations ac
LEFT JOIN table1 t 
    ON ac.column1 = t.column1 
    AND ac.column3 = t.column3
WHERE t.column1 IS NULL
ORDER BY ac.column1, ac.column3;

内容的提问来源于stack exchange,提问作者Kurasao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 16:05:22