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

GROUP BY结合多CASE语句与左连接失效问题排查

问题描述

我有两张表tblClient和tblServices,想要编写包含多CASE语句的GROUP BY子句,把每个客户的数据合并成一行,而不是多行。以下是表结构、当前查询结果、期望结果,以及我写的两个SQL Server查询(都没得到期望结果):

表概览

  • tblClient:包含客户ID(ClientID)、创建日期(CreateDate)、服务ID(ServiceID)字段
  • tblServices:包含服务ID(ServiceID)、服务名称字段,其中服务ID对应关系为:1=厨房、2=客厅、3=餐厅、4=家庭室

当前结果

每个客户对应多行数据,每行仅标记一个服务为1,其余服务列均为0

期望结果

每个客户仅显示一行数据,所有服务列根据客户是否拥有对应服务标记为1或0

我的查询语句1

SELECT 
    c.ClientID, CreateDate,
    MAX (CASE WHEN c.ServiceID = 1 THEN 1 ELSE 0 END) AS ‘Kitchen’,
    MAX (CASE WHEN c.ServiceID = 2 THEN 1 ELSE 0 END) AS ‘Living Room’,
    MAX (CASE WHEN c.ServiceID = 3 THEN 1 ELSE 0 END) AS ‘Dining Room’,
    MAX (CASE WHEN c.ServiceID = 4 THEN 1 ELSE 0 END) AS ‘Family Room’
FROM 
    tblClient c 
LEFT JOIN 
    s.tblServices s ON s.ServiceID = s.ServiceID
GROUP BY
    c.ClientID, CreateDate, c.ServiceID 

我的查询语句2

SELECT 
    c.ClientID, CreateDate,
    (CASE WHEN c.ServiceID = 1 THEN 1 ELSE 0 END) AS ‘Kitchen’,
    (CASE WHEN c.ServiceID = 2 THEN 1 ELSE 0 END) AS ‘Living Room’,
    (CASE WHEN c.ServiceID = 3 THEN 1 ELSE 0 END) AS ‘Dining Room’,
    (CASE WHEN c.ServiceID = 4 THEN 1 ELSE 0 END) AS ‘Family Room’
FROM 
    tblClient c 
LEFT JOIN 
    s.tblServices s ON s.ServiceID = s.ServiceID
GROUP BY
    c.ClientID, CreateDate, 
    CASE WHEN c.ServiceID = 1 THEN 1 ELSE 0 END,
    CASE WHEN c.ServiceID = 2 THEN 1 ELSE 0 END, 
    CASE WHEN c.ServiceID = 3 THEN 1 ELSE 0 END,
    CASE WHEN c.ServiceID = 4 THEN 1 ELSE 0 END

使用环境:SQL Server


解决方案

你的问题核心出在GROUP BY子句的字段选择,同时关联条件也存在错误:

  1. 查询1中把c.ServiceID加入GROUP BY,会导致每个不同的服务ID都生成一行,无法合并同一客户的多行数据
  2. 查询2中把每个CASE表达式都加入GROUP BY,同样会因CASE结果的差异拆分出多行
  3. 关联表时写错了条件,s.ServiceID = s.ServiceID是无效的自关联,应该关联两张表的对应字段

正确写法如下:

SELECT 
    c.ClientID, 
    c.CreateDate,
    MAX(CASE WHEN s.ServiceID = 1 THEN 1 ELSE 0 END) AS Kitchen,
    MAX(CASE WHEN s.ServiceID = 2 THEN 1 ELSE 0 END) AS [Living Room],
    MAX(CASE WHEN s.ServiceID = 3 THEN 1 ELSE 0 END) AS [Dining Room],
    MAX(CASE WHEN s.ServiceID = 4 THEN 1 ELSE 0 END) AS [Family Room]
FROM 
    tblClient c 
LEFT JOIN 
    tblServices s ON s.ServiceID = c.ServiceID  -- 修正关联条件
GROUP BY
    c.ClientID, c.CreateDate  -- 仅按客户唯一标识字段分组

关键说明:

  • 移除GROUP BY中的c.ServiceID和CASE表达式,确保同一客户的所有服务记录被合并为一行
  • 使用MAX()聚合函数,只要客户有对应服务,该列就会保留1(无对应服务则为0)
  • 用方括号[]包裹带空格的别名,符合SQL Server的语法规范
  • 修正关联表的字段匹配逻辑,保证两张表正确关联

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:10:18