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中把
c.ServiceID加入GROUP BY,会导致每个不同的服务ID都生成一行,无法合并同一客户的多行数据 - 查询2中把每个CASE表达式都加入GROUP BY,同样会因CASE结果的差异拆分出多行
- 关联表时写错了条件,
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
相关产品推荐
相关产品推荐

