我希望将每个唯一列值(Val2)的列值(Val1)显示为单个列,最多10列。
CREATE TABLE #TEMP1 (Val1 NVARCHAR(4), Val2 NVARCHAR(10));
insert into #Temp1 Values ('S01','00731')
insert into #Temp1 Values ('S02','00731')
insert into #Temp1 Values ('S03','00731')
insert into #Temp1 Values ('S04','00731')
insert into #Temp1 Values ('S05','00731')
insert into #Temp1 Values ('S06','00731')
insert into #Temp1 Values ('S07','00731')
insert into #Temp1 Values ('S08','00731')
insert into #Temp1 Values ('S09','00731')
insert into #Temp1 Values ('S07','00731')
insert into #Temp1 Values ('S04','00741')
insert into #Temp1 Values ('S01','00746')
insert into #Temp1 Values ('S01','00770')
insert into #Temp1 Values ('S01','00771')
insert into #Temp1 Values ('S02','00771')
Val1 Val2
--------------------------
S01 00731
S02 00731
S03 00731
S04 00731
S05 00731
S06 00731
S07 00731
S08 00731
S09 00731
S07 00731
S04 00741
S01 00746
S01 00770
S01 00771
S02 00771
然后我使用枢轴列显示每个唯一的Val2值,最多10个Val1值作为列。
SELECT [Val2],
c1, c2, c3, c4, c5, c6, c7, c8, c9, c10
FROM
(SELECT Val1, Val2
FROM #TEMP1) AS PivotTable
PIVOT
(
MAX([PivotTable].[Val1])
FOR
Val1
IN
(C1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
) AS PivotTable;
我希望得到如下结果:
Val2 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10
--------------------------------------------------------------------------------------
00731 S01 S02 S03 S04 S05 S06 S07 S08 S09 S07
00741 S04 NULL NULL NULL NULL NULL NULL NULL NULL NULL
00746 S01 NULL NULL NULL NULL NULL NULL NULL NULL NULL
00770 S01 NULL NULL NULL NULL NULL NULL NULL NULL NULL
00771 S01 S02 NULL NULL NULL NULL NULL NULL NULL NULL
但实际上我只是得到列的所有NULL值:
Val2 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10
--------------------------------------------------------------------------------------
00731 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
00741 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
00746 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
00770 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
00771 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
答案 0 :(得分:2)
您的要求并不完全清楚,但您似乎正在尝试创建一个名为c
的新列,然后与row_number()
关联c1, c2 c3, etc
。
如果要在子查询中使用以下内容:
SELECT Val1, Val2,
'C'+ cast(row_number() over(partition by Val2
order by val1) as varchar(10)) col
FROM TEMP1
你会得到结果:
| VAL1 | VAL2 | COL |
----------------------
| S01 | 00731 | C1 |
| S02 | 00731 | C2 |
| S03 | 00731 | C3 |
| S04 | 00731 | C4 |
| S05 | 00731 | C5 |
| S06 | 00731 | C6 |
| S07 | 00731 | C7 |
| S07 | 00731 | C8 |
| S08 | 00731 | C9 |
| S09 | 00731 | C10 |
| S04 | 00741 | C1 |
| S01 | 00746 | C1 |
| S01 | 00770 | C1 |
| S01 | 00771 | C1 |
| S02 | 00771 | C2 |
这似乎是您想要PIVOT
的结果。然后,您可以使用以下内容将PIVOT
应用于此:
SELECT Val2,
c1, c2, c3, c4, c5, c6, c7, c8, c9, c10
FROM
(
SELECT Val1, Val2,
'C'+ cast(row_number() over(partition by Val2
order by val1) as varchar(10)) col
FROM TEMP1
) src
PIVOT
(
MAX(Val1)
FOR col IN (C1, C2, C3, C4, C5, C6, C7, C8, C9, C10)
) piv;
见SQL Fiddle with Demo。那么你的最终结果是:
| VAL2 | C1 | C2 | C3 | C4 | C5 | C6 | C7 | C8 | C9 | C10 |
------------------------------------------------------------------------------------------------
| 00731 | S01 | S02 | S03 | S04 | S05 | S06 | S07 | S07 | S08 | S09 |
| 00741 | S04 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |
| 00746 | S01 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |
| 00770 | S01 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |
| 00771 | S01 | S02 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |
注意:我的结果与您要求的结果略有不同,因为我执行ORDER BY val1
会导致S07
值组合在一起。
除非您请求数据,否则数据库中没有数据顺序,因此无法保证其中一个S07
值将显示为C10
。您可以使用以下内容获得结果,但无保证结果将始终采用正确的顺序:
SELECT Val2,
c1, c2, c3, c4, c5, c6, c7, c8, c9, c10
FROM
(
SELECT Val1, Val2,
'C'+ cast(row_number() over(partition by Val2
order by (select 1)) as varchar(10)) col
FROM TEMP1
) src
PIVOT
(
MAX(Val1)
FOR col IN (C1, C2, C3, C4, C5, C6, C7, C8, C9, C10)
) piv;
见SQL Fiddle with Demo。使用order by (select 1)
会改变数据的顺序,但并不能保证它始终按照该顺序排列。结果是:
| VAL2 | C1 | C2 | C3 | C4 | C5 | C6 | C7 | C8 | C9 | C10 |
------------------------------------------------------------------------------------------------
| 00731 | S01 | S02 | S03 | S04 | S05 | S06 | S07 | S08 | S09 | S07 |
| 00741 | S04 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |
| 00746 | S01 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |
| 00770 | S01 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |
| 00771 | S01 | S02 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |
答案 1 :(得分:1)
您可以尝试使用相关子查询创建交叉表或数据透视的标准方法,并使用排名函数(此处在CTE中)来确定将值放入哪列:
;with cte as (
select Val1
, Val2
, row_number() over (partition by Val2 order by Val1) as col
--, row_number() over (partition by Val2 order by Id) as col -- Use this if you have an identity
from #TEMP1
--from (select distinct * from #TEMP1) as t -- Use this to rank distinct entries
)
select c.Val2
, (select Val1 from cte where Val2 = c.Val2 and col = 1) as c1
, (select Val1 from cte where Val2 = c.Val2 and col = 2) as c2
, (select Val1 from cte where Val2 = c.Val2 and col = 3) as c3
, (select Val1 from cte where Val2 = c.Val2 and col = 4) as c4
, (select Val1 from cte where Val2 = c.Val2 and col = 5) as c5
, (select Val1 from cte where Val2 = c.Val2 and col = 6) as c6
, (select Val1 from cte where Val2 = c.Val2 and col = 7) as c7
, (select Val1 from cte where Val2 = c.Val2 and col = 8) as c8
, (select Val1 from cte where Val2 = c.Val2 and col = 9) as c9
, (select Val1 from cte where Val2 = c.Val2 and col = 10) as c10
from cte as c
group by c.Val2
order by c.Val2
请注意,有几种方法可以确定哪个列Val2
属于哪个,我在CTE中提出了几种可能性(一些评论)。但是,您无法获得当前所需的输出,因为目前无法确定S07
应该位于第10列。也许在临时表中添加标识将捕获事件的顺序,如果这是您想要的。我也把这种可能性包含在CTE中。