我有一张表,由于某种原因,它有像这样的硬编码值:
Row ID QtyC1 QtyC2 QtyC3 QtyC4 QtyN1 QtyN2 QtyN3 QtyN4
100 10 5 8 9 11 12 5 6
101 9 11 12 5 6 10 4 9
该表有35列和大约12k条记录(意味着约500k值),并且不断添加和修改。
我试图将其转换为:
Row ID Year Period Val
100 C 1 10
100 C 2 5
100 C 3 8
100 C 4 9
100 N 1 11
100 N 2 12
100 N 3 5
100 N 4 6
到目前为止,我已设法使用此查询将其拆分为单个值:
SELECT Row ID, YP, Val
FROM (SELECT Row ID
, QtyC1 AS C1
, QtyC2 AS C2
, QtyC3 AS C3
, QtyC4 AS C4
, QtyN1 AS N1
, QtyN2 AS N2
, QtyN3 AS N3
, QtyN4 AS N4
FROM MyTable
) SUB
UNPIVOT (Val FOR YP IN (C1,C2,C3,C4,N1,N2,N3,N4)) AS PVT
这为我提供了一个识别值(例如C1
)但是如何拆分它以便我有一个数字句点和一年中的单个字符(1
和C
)?
我可以看到将字符串分成两部分是可能的,但我希望尽可能采用更清洁的方式。
答案 0 :(得分:2)
您可以使用YP
,LEFT()
,RIGHT()
等轻松拆分SUBSTRING()
字符串。我的建议是如何处理您的UNPIVOT
。看起来你有很多列UNPIVOT
所以我的建议可能是实现动态SQL来执行这个查询。你会这样做的:
declare @colsUnpivot varchar(max),
@query AS NVARCHAR(MAX),
@cols varchar(max)
select @colsUnpivot = stuff((select ','
+quotename(replace(C.name, 'Qty', ''))
from sys.columns as C
where C.object_id = object_id('yourtable') and
C.name like 'Qty%'
for xml path('')), 1, 1, '')
select @cols = stuff((select ','
+quotename(C.name) + ' as ' + replace(C.name, 'Qty', '')
from sys.columns as C
where C.object_id = object_id('yourtable') and
C.name like 'Qty%'
for xml path('')), 1, 1, '')
set @query
= 'select rowid,
left(YP, 1) YP,
cast(right(YP, len(YP) - 1) as int) period,
Val
from
(
select rowid, ' + @cols + '
from yourtable
) x1
unpivot
(
val for YP IN (' + @colsUnpivot + ')
) u'
exec(@query)
答案 1 :(得分:1)
为什么这看起来不干净?
SELECT Row ID, left(YP, 1) as year, cast(right(yp, 1) as int) as period, Val
FROM (SELECT Row ID
, QtyC1 AS C1
, QtyC2 AS C2
, QtyC3 AS C3
, QtyC4 AS C4
, QtyN1 AS N1
, QtyN2 AS N2
, QtyN3 AS N3
, QtyN4 AS N4
FROM MyTable
) SUB
UNPIVOT (Val FOR YP IN (C1,C2,C3,C4,N1,N2,N3,N4)) AS PVT