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

SQL多表查询:如何判断每个行程是否包含活动日

多表关联去重及行程活动状态判断方案

问题背景

现有三张表:

  • USERS表:id_user(用户ID)、name(用户名)
  • TRAVEL表:id_travel(行程ID)、id_user(关联用户ID)
  • TRAVEL_DAYS表:id_tdays(日期ID)、id_travel(关联行程ID)、day_has_activities(当日是否有活动)

执行原关联查询时,因单一行程对应多个日期,结果出现重复行:

SELECT 
t.id_travel,
u.name,
td.day_has_activities
FROM travel t
left join users u on u.id_user = t.id_user
left join travel_days td on td.id_travel = t.id_travel

使用DISTINCT无法解决问题,因为day_has_activities仅代表单日期状态,无法覆盖整个行程。需求为每个行程仅返回一条记录,新增travel_has_activities字段,判断该行程是否存在任意一日有活动(存在返回yes,否则返回no)。

错误SQL问题分析

你尝试的SQL无法执行,核心问题:

  1. 子查询中from t错误引用主查询的TRAVEL表,实际应查询TRAVEL_DAYS表
  2. 子查询未添加与主行程的关联条件,逻辑不成立
  3. 即使修正子查询,未处理多日期导致的重复行问题

正确实现方案

方案一:先聚合行程日期数据再关联

先对TRAVEL_DAYS按行程分组,提前判断该行程是否有活动日期,再与其他表关联,从根源避免重复行:

SELECT 
    t.id_travel,
    u.name,
    CASE 
        WHEN td.has_activity = 1 THEN 'yes' 
        ELSE 'no' 
    END AS travel_has_activities
FROM travel t
LEFT JOIN users u ON u.id_user = t.id_user
LEFT JOIN (
    -- 按行程分组,标记是否存在有活动的日期
    SELECT 
        id_travel,
        MAX(CASE WHEN day_has_activities = 'yes' THEN 1 ELSE 0 END) AS has_activity
    FROM travel_days
    GROUP BY id_travel
) td ON td.id_travel = t.id_travel

方案二:使用EXISTS子查询直接判断

通过EXISTS子查询直接检查当前行程是否存在有活动的日期,无需分组,查询性能更高效(找到符合条件的记录即停止遍历):

SELECT 
    t.id_travel,
    u.name,
    CASE 
        WHEN EXISTS (
            SELECT 1 
            FROM travel_days td 
            WHERE td.id_travel = t.id_travel 
              AND td.day_has_activities = 'yes'
        ) THEN 'yes' 
        ELSE 'no' 
    END AS travel_has_activities
FROM travel t
LEFT JOIN users u ON u.id_user = t.id_user

说明

两种方案均能保证每个行程仅返回一条记录,且准确判断行程是否存在活动日期。方案二更适合数据量较大的场景,因为EXISTS的查询逻辑更轻量化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 23:35:27