SQL Server 2012按key将行转列(每组最多4行)的实现需求
解决方案:SQL Server 2012 按分组行转固定列
你可以通过分组排序+条件聚合的方式实现需求,具体步骤如下:
1. 示例表与数据(补全你的定义)
DECLARE @resu TABLE ( header_id INT, client_id INT, appointment_id INT, on_date DATE, on_time TIME, room_id INT ); -- 插入测试数据 INSERT INTO @resu VALUES (1, 101, 1, '2024-05-01', '09:00:00', 10), (1, 102, 2, '2024-05-01', '09:00:00', 10), (1, 103, 3, '2024-05-01', '09:00:00', 10), (2, 201, 1, '2024-05-02', '14:30:00', 15), (2, 202, 2, '2024-05-02', '14:30:00', 15), (3, 301, 1, '2024-05-03', '10:00:00', 20);
2. 行转列实现SQL
SELECT header_id, on_date, on_time, room_id, -- 按序号提取对应位置的client_id,不足则返回NULL MAX(CASE WHEN rn = 1 THEN client_id END) AS client_id1, MAX(CASE WHEN rn = 2 THEN client_id END) AS client_id2, MAX(CASE WHEN rn = 3 THEN client_id END) AS client_id3, MAX(CASE WHEN rn = 4 THEN client_id END) AS client_id4 FROM ( -- 分组内按appointment_id排序,生成行序号 SELECT *, ROW_NUMBER() OVER (PARTITION BY header_id ORDER BY appointment_id) AS rn FROM @resu ) t GROUP BY header_id, on_date, on_time, room_id;
逻辑说明
- 子查询中使用
ROW_NUMBER()函数,按header_id分组、appointment_id升序排序,为每组内的行分配1~N的序号(rn) - 外层通过
CASE语句配合MAX聚合,根据序号提取对应位置的client_id:当某组不足4行时,超出序号的CASE会返回NULL,MAX函数不影响NULL值 - 由于每组的
on_date、on_time、room_id是共有字段,直接放入GROUP BY即可保留
输出结果示例
| header_id | on_date | on_time | room_id | client_id1 | client_id2 | client_id3 | client_id4 |
|---|---|---|---|---|---|---|---|
| 1 | 2024-05-01 | 09:00:00 | 10 | 101 | 102 | 103 | NULL |
| 2 | 2024-05-02 | 14:30:00 | 15 | 201 | 202 | NULL | NULL |
| 3 | 2024-05-03 | 10:00:00 | 20 | 301 | NULL | NULL | NULL |
内容的提问来源于stack exchange,提问作者PanosPlat
相关产品推荐
相关产品推荐

