我有一个没有主键的表,但有一个可以用作主键的ID字段。我想将此表转换为可用于跟踪插入,更新和删除的内容。只添加一个Identity列不是一个可行的解决方案,因为每天晚上都会重新创建表。
该表格如下:
ID Specialty
-- ---------
01 Fam Med
02 Fam Med
02 Int Med
03 Surgery
03 Thor Sur
03 Card Sur
04 Undersea
我想将其转换为类似以下的内容,并使用ID作为主键:
ID Specialty1 Specialty2 Specialty3
-- ---------- ---------- ----------
01 Fam Med
02 Fam Med Int Med
03 Surgery Thor Sur Card Sur
04 Undersea
我倾向于使用SQL pivot操作符,但我对Axots不够熟悉,我不确定在这种情况下它是否合适。
提前感谢您的意见。
答案 0 :(得分:1)
您需要执行PIVOT的SQL是:
SELECT ID,
Specialty1,
Specialty2,
Specialty3
FROM ( SELECT ID,
Specialty,
SpecialtyNum = 'Specialty' +
CAST(ROW_NUMBER() OVER(PARTITION BY ID
ORDER BY Specialty) AS VARCHAR(10))
FROM T
) AS t
PIVOT
( MAX(Specialty)
FOR SpecialtyNum IN ([Specialty1], [Specialty2], [Specialty3])
) AS pvt;
<强> Example on SQL Fiddle 强>
关键是添加一个可以转动的列,因此子查询的结果为:
SELECT ID,
Specialty,
SpecialtyNum = 'Specialty' +
CAST(ROW_NUMBER() OVER(PARTITION BY ID
ORDER BY Specialty) AS VARCHAR(10))
FROM T;
给你:
ID Specialty SpecialtyNum
-- --------- -------------
01 Fam Med Specialty1
02 Fam Med Specialty1
02 Int Med Specialty2
03 Surgery Specialty1
03 Thor Sur Specialty2
03 Card Sur Specialty3
04 Undersea Specialty1
然后您可以转到SpecialtyNum
列。由于specialNum的每个值对于ID都是唯一的,因此通过聚合不会丢失数据。
但是,如果需要未知数量的专业,您需要动态生成它:
DECLARE @Cols NVARCHAR(MAX) =
STUFF(( SELECT DISTINCT ',[Specialty' + CAST(ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Specialty) AS VARCHAR(10)) + '] '
FROM T
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '');
DECLARE @SQL NVARCHAR(MAX) =
'SELECT ID, ' + @Cols +
'FROM ( SELECT ID,
Specialty,
SpecialtyNum = ''Specialty'' +
CAST(ROW_NUMBER() OVER(PARTITION BY ID
ORDER BY Specialty) AS VARCHAR(10))
FROM T
) AS t
PIVOT
( MAX(Specialty)
FOR SpecialtyNum IN (' + @Cols + ')
) AS pvt;';
EXECUTE sp_executesql @SQL;
<强> Example on SQL Fiddle 强>