当前位置: 代码迷 >> Sql Server >> SQL多行转多列如何实现呢
  详细解决方案

SQL多行转多列如何实现呢

热度:84   发布时间:2016-04-24 09:51:00.0
SQL多行转多列怎么实现呢
问题:假设有张学生成绩表(tb)如下:
姓名 课程 分数
张三 语文 74
张三 数学 83
张三 物理 93
张三 德语 null
李四 语文 74
李四 数学 84
李四 物理 94
李四 英语 80
想变成(得到如下结果): 
姓名 语文 数学 物理 英语 德语
---- ---- ---- ----
李四 74   84   94  ? 60
张三 74   83   93  80 ?
-------------------
怎么实现这个这个功能呢,请大神指教,多谢啦
------解决思路----------------------
select 姓名,
sum(case when 课程='语文' then 分数 else 0 end)  语文,
sum(case when 课程='数学' then 分数 else 0 end)  数学,
sum(case when 课程='物理' then 分数 else 0 end)  物理,
sum(case when 课程='英语' then 分数 else 0 end)  英语,
sum(case when 课程='德语' then 分数 else 0 end)  德语
from tb
group by 姓名
------解决思路----------------------
你参考一下
SELECT P.* FROM [学生成绩表]PIVOT(MAX([分数])FOR[课程]IN([语文],[数学],[物理],[英语],[德语]))P

如果课程不固定,还可以用动态处理

------解决思路----------------------

------解决思路----------------------
-- 用临时表做的测试数据
WITH course(ID,课程) AS (
    SELECT 1,'语文' UNION ALL
    SELECT 2,'数学' UNION ALL
    SELECT 3,'物理' UNION ALL
    SELECT 4,'英语' UNION ALL
    SELECT 5,'德语' UNION ALL
    SELECT 6,'法语'
)
SELECT *
  INTO #course
  FROM course;

WITH student(姓名) AS (
    SELECT '张三' UNION ALL
    SELECT '李四' UNION ALL
    SELECT '王五'
)
SELECT *
  INTO #student
  FROM student;

WITH tb (姓名,课程,分数) AS (
    SELECT '张三','语文',74 UNION ALL
    SELECT '张三','数学',83 UNION ALL
    SELECT '张三','物理',93 UNION ALL
    SELECT '张三','德语',null UNION ALL
    SELECT '李四','语文',74 UNION ALL
    SELECT '李四','数学',84 UNION ALL
    SELECT '李四','物理',94 UNION ALL
    SELECT '李四','英语',80 
)
SELECT *
  INTO #tb
  FROM tb;

-- 以下为查询部分,你自己改为实际的表名
DECLARE @sql varchar(max),
        @columns varchar(max)

SET @columns = ''

  SELECT  @columns = @columns + ', [' + [课程] + ']' 
    FROM #course
ORDER BY ID

SET @sql = '
    SELECT *
      FROM (
                SELECT s.姓名,
                       c.课程,
                       ISNULL(t.分数,60) AS 分数
                  FROM #student s
                  JOIN #course c
                    ON 1=1
             LEFT JOIN #tb t
                    ON t.姓名 = s.姓名
                   AND t.课程 = c.课程
           ) l
     PIVOT (
            Max (分数)
            FOR 课程 IN ( ' + SubString(@columns, 3, Len(@columns)-2) + ')
           ) AS p'
--PRINT @sql
EXEC (@sql)

姓名        语文        数学        物理        英语        德语        法语
---- ----------- ----------- ----------- ----------- ----------- -----------
李四          74          84          94          80          60          60
王五          60          60          60          60          60          60
张三          74          83          93          60          60          60

------解决思路----------------------
ISNULL(t.分数,60) AS 分数

更改为
ISNULL(Convert(varchar(11),t.分数),'?') AS 分数


你既然要求几万*上千的表格,除了乘积还能用什么方法?
  相关解决方案