首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >枢轴未知列内容

枢轴未知列内容
EN

Stack Overflow用户
提问于 2013-11-26 09:10:38
回答 2查看 126关注 0票数 2

我有以下数据,但是我不知道之前表的内容

代码语言:javascript
复制
courses table
-------------
id  | name
-------------
7   | math
99  | geology
4   | ethics
5   | sports
33  | english
29  | math boot camp

我需要输出

代码语言:javascript
复制
course1_id | course1_name | course2_id | course2_name | course3_id | course3_name
         7 | math         |         99 |      geology |          4 |       ethics

SQLFiddle演示

我试过了

代码语言:javascript
复制
select case when id = 7 then id end as course1_id, 
       case when id = 7 then name end as course1_name
from courses

但是这会返回多个行,而不是一个,而且由于我不知道id,所以不能使用该方法。有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-26 09:30:56

您需要的SQL是:

代码语言:javascript
复制
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;

但是对于未知的内容,您需要动态地生成这样的内容:

代码语言:javascript
复制
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示例

实现同样结果的另一种方法是:

代码语言:javascript
复制
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子句即可。

票数 4
EN

Stack Overflow用户

发布于 2013-11-26 09:52:20

我会用枢轴。由于您不知道表的长度,所以它必须是动态的:

代码语言:javascript
复制
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);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20212611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档