如何实现SQL查询中BedType列按RoomId仅首行显示值其余为空?
需求与问题描述
我有一张包含BedType、RoomId、FirstName列的表,该表由以下SQL查询生成:
SELECT B.Name 'BedType',Ro.Id'RoomId',C.FirstName From Customers C JOIN Rooms Ro ON Ro.Id = C.RoomId JOIN BedTypes B ON B.Id = Ro.BedTypeId ORDER BY Ro.ReservationId
我的需求是:将BedType列处理为字符串类型,按RoomId分组后,每组仅首行显示对应的BedType值,其余行的BedType列置空。我尝试了以下SQL语句但未成功,寻求解决方案:
SELECT ( CASE WHEN B.Id =1 THEN (SELECT Ro.Id ) WHEN B.Id =3 THEN NULL WHEN B.Id = 4 THEN Null END ) AS Trial ,B.Name 'BedType',Ro.Id'RoomId',C.FirstName From Customers C JOIN Rooms Ro ON Ro.Id = C.RoomId JOIN BedTypes B ON B.Id = Ro.BedTypeId ORDER BY Ro.ReservationId
解决方案
要实现这个需求,核心是用窗口函数标记每个RoomId分组内的首行,再通过CASE语句控制BedType的显示。以下是主流SQL数据库通用的实现方式:
SELECT CASE WHEN rn = 1 THEN B.Name ELSE '' END AS BedType, Ro.Id AS RoomId, C.FirstName FROM ( SELECT B.Name, Ro.Id, C.FirstName, -- 按RoomId分组,组内以ReservationId排序,为每行分配行号 ROW_NUMBER() OVER (PARTITION BY Ro.Id ORDER BY Ro.ReservationId) AS rn FROM Customers C JOIN Rooms Ro ON Ro.Id = C.RoomId JOIN BedTypes B ON B.Id = Ro.BedTypeId ) t ORDER BY RoomId, rn;
说明:
- 内层查询通过
ROW_NUMBER() OVER (PARTITION BY Ro.Id ORDER BY Ro.ReservationId),为每个RoomId分组内的行分配行号rn,分组内首行的rn为1。 - 外层查询用CASE语句判断:当
rn=1时显示BedType名称,否则显示空字符串(若需要置为NULL,替换''为NULL即可)。 - 最终按RoomId和行号排序,确保分组内的顺序符合预期。
该方案适用于MySQL 8.0+、SQL Server、PostgreSQL、Oracle等支持窗口函数的数据库。
内容的提问来源于stack exchange,提问作者Eymen Efe Altun
相关产品推荐
相关产品推荐

