【问题标题】:Table transformation logic in SQLSQL中的表转换逻辑
【发布时间】:2017-10-29 14:26:22
【问题描述】:

我有一张桌子 T:

CREATE TABLE T 
(
     id INT,
     type VARCHAR(200),
     type_value VARCHAR(10),
     value  VARCHAR(200)
);

INSERT INTO T VALUES (1, 'RoomColor', 'room1', 'yellow');
INSERT INTO T VALUES (1, 'RoomColor', 'room2', 'red');
INSERT INTO T VALUES (2, 'RoomColor', 'room1', 'blue');
INSERT INTO T VALUES (2, 'RoomColor', 'room1', 'pink');
INSERT INTO T VALUES (3, 'RoomColor', 'room1', 'white');
INSERT INTO T VALUES (3, 'RoomColor', 'room2', 'grey');
INSERT INTO T VALUES (3, 'RoomColor', 'room2', 'brown');
INSERT INTO T VALUES (4, 'RoomColor', 'room3', 'green');

我需要把它转换成:

id   BedRoomColor    DiningRoomColor 
------------------------------------------- 
 1    yellow           red
 2    blue             pink
 3    white            grey
 4    green            null   

转型背后的逻辑:

  1. 如果有两个以上房间 type_value 则丢弃第三个房间 type_value
  2. 如果有多个房间 type_value(例如 room1,room1room2,room2room1,room2),则为相同的 id然后使用第一个 type_value 创建为 BedRoomColor 和第二个 type_value 创建 DiningRoomColor
  3. 如果只有 1 个房间类型值 (例如,房间 1 或房间 2 或房间 3),则对应的值( 红色、绿色、黄色等)将为放置在 BedRoomColor 和 DiningRoomColor 将是 null

这几天我一直在为这个逻辑苦苦挣扎。谁能帮帮我。

谢谢

【问题讨论】:

  • 谷歌:“SQL Server pivot”。
  • 检查过了。但仍然在逻辑部分苦苦挣扎。

标签: sql sql-server


【解决方案1】:

你可以使用这个脚本

;WITH CTE AS (
SELECT *, RN = ROW_NUMBER() OVER(PARTITION BY id ORDER BY type_value) FROM T 
)
SELECT id, [1] BedRoomColor, [2] DiningRoomColor FROM
    (SELECT id,value, RN FROM CTE  ) SRC
    PIVOT (MAX(value) FOR RN IN ([1], [2]) ) AS PVT

结果:

id          BedRoomColor       DiningRoomColor 
----------- ------------------ --------------- 
1           yellow             red
2           blue               pink
3           white              grey
4           green              NULL

【讨论】:

  • 非常感谢。试试看
【解决方案2】:

另一种方法是在查询中添加type

;with tt as (
    select *,
        row_number() over (partition by [type], id  order by type_value) rn
        --                              ^^^^^^ I add type to support other types if there is
    from t
)
select id,
    max(case when [type] = 'RoomColor' and rn = 1 then [value] end) 'BedRoomColor',
    max(case when [type] = 'RoomColor' and rn = 2 then [value] end) 'DiningRoomColor'
from tt
group by id;

SQL Server Fiddle Demo

【讨论】:

  • 非常感谢朋友。
【解决方案3】:

试试这个:

with tmp as (
select T.*, rownumber() over(patition by id order by type_value) rang
from T
)
select f1.id, f1.value as BedRoomColor, f2.value as DiningRoomColor 
from tmp f1
left outer join tmp f2 on f1.id=f2.id and f2.rang=2 
where f1.rang=1

【讨论】:

  • 非常感谢。试试看:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-29
  • 1970-01-01
  • 1970-01-01
  • 2019-02-23
相关资源
最近更新 更多