zoukankan      html  css  js  c++  java
  • sql server行转列 列转行交叉表实现[转]

    主要应用case语句来解决行转列的问题
    行转列问题主要分为两类

    1)简单的行转列问题:

    示例表:

    id sid           course result

    1   2005001 语文     80.0
    2   2005001 数学     90.0
    3   2005001 英语     80.0
    4   2005002 语文     56.0
    5   2005002 数学     69.0
    6   2005002 英语     89.0

    执行

    select sid,语文=isnull(sum(case course when '语文' then result end),0),
       数学=isnull(sum(case course when '数学' then result end),0),
       英语=isnull(sum(case course when '英语' then result end),0)
       from result
       group by sid
       order by sid


    得出结果

    sid           语文 数学 英语

    2005001 80.0 90.0 80.0
    2005002 56.0 69.0 89.0


    2)较为复杂的行转列

    表1:course

    id name

    1 语文
    2 数学
    3 英语


    表2:result

    id sid          course result

    1 2005001 语文      80.0
    2 2005001 数学      90.0
    3 2005001 英语      80.0
    4 2005002 语文      56.0
    5 2005002 数学      69.0
    6 2005002 英语      89.0


    declare @sql varchar(8000)
    set @sql='select sid'
    select @sql=@sql+','+course.name+'=isnull(sum(case course when '''+course.name+''' then result end),0)'
    from course order by id
    set @sql=@sql+' from result group by sid order by sid'
    print @sql
    exec(@sql)


    得出结果

    sid           语文 数学 英语

    2005001 80.0 90.0 80.0
    2005002 56.0 69.0 89.0

    -----------------列转行---------------------------------------------------------------------------------------------------------

    有字符串'1,2,3,4,5,,6,7,8,'这样的不定长字符串,要求将其转成一列N行来存储,也就是列转行,哪种方式最快.

    经过讨论,下列方式最快.

    declare @var varchar(8000)
        ,@sql varchar(8000)
        ,@last varchar(1)
        ,@ctrl int
    set @var='1,2,3,4,5,,6,7,'
    set @ctrl=0
    while @ctrl=0
    begin
    if (select charindex(',,',@var))>0
        select @var=replace(@var,',,',',')
    else
        set @ctrl=1
    end

    set @last=right(@var,1)

    if @last=','
    set @var=left(@var,len(@var)-1)

    set @sql='select '+replace(@var,',',' union all select '


     


    -------------------------------------------------可运行的------------------------------------

    --交叉表语句的实现:
    CREATE TABLE Test
    (
    id int IDENTITY(1,1) NOT NULL,
    name nvarchar(50) NULL,
    subject nvarchar(50) NULL,
    Source numeric(18,0) NULL
    )

    GO

    INSERT INTO [test] ([name],[subject],[Source]) values (N'张三',N'语文',60)
    INSERT INTO [test] ([name],[subject],[Source]) values (N'李四',N'数学',70)
    INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'英语',80)
    INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'数学',75)
    INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'语文',57)
    INSERT INTO [test] ([name],[subject],[Source]) values (N'李四',N'语文',80)
    INSERT INTO [test] ([name],[subject],[Source]) values (N'张三',N'英语',100)

    Go

    SELECT * FROM TEST

    --用于:交叉表的列数是确定的
    select name,sum(case subject when '数学' then source else 0 end) as '数学',
    sum(case subject when '英语' then source else 0 end) as '英语',
    sum(case subject when '语文' then source else 0 end) as '语文'
    from test
    group by name

    --用于:交叉表的列数是不确定的
    declare @sql varchar(8000)
    set @sql = 'select name'
    select @sql = @sql + ',sum(case subject when '''+subject+'''
          then source else 0 end) as '''+subject+''' '
    from (select distinct subject from test) as a
    select @sql = @sql + ' from test group by name'
    exec(@sql)

  • 相关阅读:
    自制“低奢内”CSS3注册表单,包含JS验证哦。请别嫌弃,好吗?。
    自制“低奢内”CSS3登入表单,包含JS验证,请别嫌弃哦。
    到网上收集了一个“高大上”的CSS3登入表单和大家分享一下
    利用:before和:after伪类制作CSS3 圆形按钮 含demo
    Font Awesome 4.0.3 提供了369个网页常用的矢量字体图标,新浪、人人 的矢量图标也到其中哟
    CSS3无前缀脚本prefixfree.js与Animatable使用介绍
    JAVA 利用Dom4j实现英语六级词汇查询 含演示地址
    JAVA中 XML与数据库互转 学习笔记三
    JAVA与DOM解析器提高(DOM/SAX/JDOM/DOM4j/XPath) 学习笔记二
    JAVA与DOM解析器基础 学习笔记
  • 原文地址:https://www.cnblogs.com/hanguoji/p/1661756.html
Copyright © 2011-2022 走看看