我有以下数据,但是我不知道之前表的内容
courses table
-------------
id | name
-------------
7 | math
99 | geology
4 | ethics
5 | sports
33 | english
29 | math boot camp我需要输出
course1_id | course1_name | course2_id | course2_name | course3_id | course3_name
7 | math | 99 | geology | 4 | ethicsSQLFiddle演示
我试过了
select case when id = 7 then id end as course1_id,
case when id = 7 then name end as course1_name
from courses但是这会返回多个行,而不是一个,而且由于我不知道id,所以不能使用该方法。有什么想法吗?
发布于 2013-11-26 09:30:56
您需要的SQL是:
SELECT Course1_ID = MAX(CASE WHEN RowNum = 1 THEN ID END),
Course1_Name = MAX(CASE WHEN RowNum = 1 THEN Name END),
Course2_ID = MAX(CASE WHEN RowNum = 2 THEN ID END),
Course2_Name = MAX(CASE WHEN RowNum = 2 THEN Name END),
Course3_ID = MAX(CASE WHEN RowNum = 3 THEN ID END),
Course3_Name = MAX(CASE WHEN RowNum = 3 THEN Name END)
FROM ( SELECT ID,
Name,
RowNum = ROW_NUMBER() OVER(ORDER BY ID)
FROM Courses
) C;但是对于未知的内容,您需要动态地生成这样的内容:
DECLARE @SQL NVARCHAR(MAX) = 'SELECT ' +
STUFF(( SELECT ',Course' + RowNum + '_ID = MAX(CASE WHEN RowNum = ' + RowNum + ' THEN ID END)
,Course' + RowNum + '_Name = MAX(CASE WHEN RowNum = ' + RowNum + ' THEN Name END)'
FROM ( SELECT RowNum = CAST(ROW_NUMBER() OVER(ORDER BY ID) AS VARCHAR(10))
FROM Courses
) c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '') +
' FROM ( SELECT ID,
Name,
RowNum = ROW_NUMBER() OVER(ORDER BY ID)
FROM Courses
) C;'
EXECUTE SP_EXECUTESQL @SQL;SQL Fiddle示例
实现同样结果的另一种方法是:
DECLARE @SQL NVARCHAR(MAX) = '';
SELECT @SQL = @SQL +
',Course' + RowNum + '_ID = MAX(CASE WHEN RowNum = ' + RowNum + ' THEN ID END)
,Course' + RowNum + '_Name = MAX(CASE WHEN RowNum = ' + RowNum + ' THEN Name END)'
FROM ( SELECT RowNum = CAST(ROW_NUMBER() OVER(ORDER BY ID) AS VARCHAR(10))
FROM Courses
) c;
SET @SQL = 'SELECT ' + STUFF(@SQL, 1, 1, '') + '
FROM ( SELECT ID,
Name,
RowNum = ROW_NUMBER() OVER(ORDER BY ID)
FROM Courses
) c;';
EXECUTE SP_EXECUTESQL @SQL;这将移除用于将行连接到列中的昂贵XML扩展。
SQL Fiddle示例
如果课程的顺序是相关的,那么只需更改ROW_NUMBER函数中的order子句即可。
发布于 2013-11-26 09:52:20
我会用枢轴。由于您不知道表的长度,所以它必须是动态的:
declare @count int;
declare @i int;
declare @p varchar(max) = '';
declare @s varchar(max) = '';
select @count = COUNT(*) from courses;
set @i = 1;
while @i <= @count
begin
set @p = @p + ', [course'+convert(varchar,@i)+'_id], [course'+convert(varchar,@i)+'_name]';
set @i = @i+1;
end
set @p = substring (@p,3,len(@p)-2);
set @s = 'select '+@p+'
from
( select ''course''+convert(varchar,ROW_NUMBER() over (order by convert(int,id)))+''_id'' as rn
, courses.id as c
from courses
union all
select ''course''+convert(varchar,ROW_NUMBER() over (order by convert(int,id)))+''_name'' as rn
, courses.name as c
from courses ) as sourcetable
pivot (
max(c)
for rn in ('+@p+')
) as pivottable';
execute(@s);https://stackoverflow.com/questions/20212611
复制相似问题