AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 192532
Accepted
SQLserving
SQLserving
Asked: 2017-12-07 06:37:13 +0800 CST2017-12-07 06:37:13 +0800 CST 2017-12-07 06:37:13 +0800 CST

长数据动态转换为多列宽数据

  • 772

我正在尝试转换长数据:

ID|SchoolID|Section|RepScore|SportsScore|PartyScore  
1 |20      |1      |23.2    |70.2       |42.3          
2 |20      |6      |65.2    |75.8       |52.3        
3 |20      |7      |77.2    |72.2       |66.3       
4 |21      |10     |13.2    |40.2       |72.3         
5 |21      |11     |25.2    |55.8       |72.3         
6 |21      |12     |37.2    |62.2       |76.3       

到宽数据(我只使用前三行来保持简短):

SchoolID|RpScr1|RpScr6|RpScr7|SprtScr1|SprtScr6|SprtScr7|Prty1|Prty6|Prty7  
20      |23.2  |65.2  |77.2  |70.2    |75.8    |72.2    |42.3 |52.3 |66.3 

我试过这个:

DECLARE @cols VARCHAR(1000)
DECLARE @cols2 VARCHAR(1000)
DECLARE @cols3 VARCHAR(1000)
DECLARE @sqlquery VARCHAR(2000)
SELECT  @cols = STUFF(( SELECT distinct  '], [a' + cast([Section] as varchar)
                        FROM [dbo].[SchoolData] FOR XML PATH('') ), 1, 2, '') + ']'
SELECT  @cols2 = STUFF(( SELECT distinct  '], [b' + cast([Section] as varchar)
                        FROM [dbo].[SchoolData] FOR XML PATH('') ), 1, 2, '') + ']'
SELECT  @cols3 = STUFF(( SELECT distinct  '], [c' + cast([Section] as varchar)
                        FROM [dbo].[SchoolData] FOR XML PATH('') ), 1, 2, '') + ']'
SET @sqlquery = 'SELECT * FROM
      (SELECT z.Section,z.RepScore,z.SportsScore,z.PartyScore
       FROM [dbo].[SchoolData] z) base
       PIVOT (Max(RepScore) FOR [Section] IN (' + @cols + ')) AS finalpivot
       PIVOT (Max(SportsScore) FOR [Section] IN (' + @cols + ')) AS finalpivot2
       PIVOT (Max(PartyScore) FOR [Section] IN (' + @cols + ')) AS finalpivot3'


EXECUTE ( @sqlquery )

这是我得到的错误:Msg 8114, Level 16, State 1, Line 7 将数据类型 nvarchar 转换为 int 时出错。消息 473,级别 16,状态 1,第 7 行 PIVOT 运算符中提供了不正确的值“a9”。消息 207,级别 16,状态 1,第 8 行 列名“部分”无效。

当我尝试这样的一个时:

DECLARE @cols VARCHAR(1000)  
DECLARE @sqlquery VARCHAR(2000)  
    SELECT  @cols = STUFF(( SELECT distinct  '], [a' + cast([Section] as varchar)  
                            FROM [dbo].[SchoolData] FOR XML PATH('') ), 1, 2, '') + ']'    
SET @sqlquery = 'SELECT * FROM  
          (SELECT z.Section,z.RepScore,z.SportsScore,z.PartyScore  
           FROM [dbo].[SchoolData] z) base  
           PIVOT (Max(RepScore) FOR [Section] IN (' + @cols + ')) AS   finalpivot' 

它仅适用于一列,并给出类似 [1]、[6]、[7] 的列名称。但它不适用于我需要的多个列。有任何想法吗?

sql-server xml
  • 3 3 个回答
  • 3925 Views

3 个回答

  • Voted
  1. KumarHarsh
    2017-12-09T03:23:43+08:002017-12-09T03:23:43+08:00

    你在找这个吗

    CREATE TABLE #T(ID INT,SchoolID INT,Section INT,RepScore DECIMAL(5,2)
    ,SportsScore DECIMAL(5,2),PartyScore DECIMAL(5,2))
    INSERT INTO #T VALUES
    (1,20,1 ,23.2,70.2,42.3)         
    ,(2,20,6 ,65.2,75.8,52.3)       
    ,(3,20,7 ,77.2,72.2,66.3)      
    ,(4,21,10,13.2,40.2,72.3)        
    ,(5,21,11,25.2,55.8,72.3)        
    ,(6,21,12,37.2,62.2,76.3) 
    --SELECT * FROM #T
    
    DECLARE @colRpName VARCHAR(1000)
    DECLARE @colRpVal VARCHAR(1000)
    DECLARE @colSportVal VARCHAR(1000)
    DECLARE @colPartyVal VARCHAR(1000)
    DECLARE @sqlquery VARCHAR(2000)
    
    SELECT  
    @colRpName = STUFF(( SELECT distinct  '], [' + cast([Section] as varchar)
                            FROM #T t1  FOR XML PATH('') ), 1, 2, '') + ']'
    ,  @colRpVal = STUFF(( SELECT distinct  ', [' + cast([Section] as varchar) +'] as '+'[a ' + cast([Section] as varchar)+']'
                            FROM #T t1  FOR XML PATH('') ), 1, 2, '') + ''
    ,  @colSportVal = STUFF(( SELECT distinct  ', [' + cast([Section] as varchar) +'] as '+'[b ' + cast([Section] as varchar)+']'
                            FROM #T t1  FOR XML PATH('') ), 1, 2, '') + ''
    ,  @colPartyVal = STUFF(( SELECT distinct  ', [' + cast([Section] as varchar) +'] as '+'[c ' + cast([Section] as varchar)+']'
                            FROM #T t1 FOR XML PATH('') ), 1, 2, '') + ''
    from #T t
    
    --SELECT @colRpName,@colRpVal
    
    SET @sqlquery = '
    SELECT fp.SchoolID,'+@colRpVal+'
    ,'+@colSportVal+'
    ,'+@colPartyVal+'
    FROM  
    (SELECT SchoolID,[section],RepScore
    
    FROM #T z) base  
    PIVOT (sum(RepScore) FOR [section] IN ('+@colRpName+')) AS   fp
    CROSS APPLY 
    (
    SELECT fp1.SchoolID,'+@colSportVal+'
    FROM  
    (SELECT SchoolID,[section],SportsScore
    
    FROM #T z) base1  
    PIVOT (sum(SportsScore) FOR [section] IN ('+@colRpName+')) AS   fp1
    WHERE fp1.SchoolID=fp.SchoolID
    )ca
    CROSS APPLY 
    (
    SELECT fp2.SchoolID,'+@colPartyVal+'
    FROM  
    (SELECT SchoolID,[section],PartyScore
    
    FROM #T z) base2
    PIVOT (sum(PartyScore) FOR [section] IN ('+@colRpName+')) AS   fp2
    WHERE fp2.SchoolID=fp.SchoolID
    )ca1
      ' 
    
    --print @sqlquery
      EXEC(@sqlquery)-- please use sp_executesql
    
    DROP TABLE #T
    
    • 1
  2. irimias
    2017-12-09T07:48:18+08:002017-12-09T07:48:18+08:00

    如果您已经知道 Section + score 类型的所有可能值,您可以尝试以下枢轴/反枢轴技巧:

    create table my_table(ID int, SchoolID int, Section int, RepScore decimal(8, 2), SportsScore decimal(8, 2), PartyScore decimal(8, 2))
    insert into my_table
    values(  1, 20, 1 , 23.2, 70.2, 42.3),      
            (2, 20, 6 , 65.2, 75.8, 52.3),    
            (3, 20, 7 , 77.2, 72.2, 66.3),   
            (4, 21, 10, 13.2, 40.2, 72.3),     
            (5, 21, 11, 25.2, 55.8, 72.3),     
            (6, 21, 12, 37.2, 62.2, 76.3)     
            (1, 20, 1 , 23.2, 70.2, 42.3),      
            (2, 20, 6 , 65.2, 75.8, 52.3),    
            (3, 20, 7 , 77.2, 72.2, 66.3),   
            (4, 21, 10, 13.2, 40.2, 72.3),     
            (5, 21, 11, 25.2, 55.8, 72.3),     
            (6, 21, 12, 37.2, 62.2, 76.3)  
    
    
    
    
    select  SchoolID, 
            [RepScore1],
            [SportsScore1],
            [PartyScore1],
            [RepScore6],
            [SportsScore6],
            [PartyScore6],
            [RepScore7],
            [SportsScore7],
            [PartyScore7],
            [RepScore10],
            [SportsScore10],
            [PartyScore10],
            [RepScore11],
            [SportsScore11],
            [PartyScore11],
            [RepScore12],
            [SportsScore12]
    from (
        select SchoolID, score, col+cast(Section as varchar) as col
        from my_table t
        unpivot(score for col in (RepScore, SportsScore, PartyScore)) up
        ) t
    pivot(max(score) for col in([RepScore1],
                                [SportsScore1],
                                [PartyScore1],
                                [RepScore6],
                                [SportsScore6],
                                [PartyScore6],
                                [RepScore7],
                                [SportsScore7],
                                [PartyScore7],
                                [RepScore10],
                                [SportsScore10],
                                [PartyScore10],
                                [RepScore11],
                                [SportsScore11],
                                [PartyScore11],
                                [RepScore12],
                                [SportsScore12])) p
    
    • 1
  3. Best Answer
    SQLserving
    2017-12-12T05:48:39+08:002017-12-12T05:48:39+08:00

    这就是我最终做到的方式。

    DECLARE @cols VARCHAR(2000)  
    DECLARE @sqlquery2 VARCHAR(2000)  
    DECLARE @sqlquery3 VARCHAR(2000)  
    DECLARE @sqlquery4 VARCHAR(2000)  
    DECLARE @sqlquery5 VARCHAR(2000)  
    DECLARE @sqlquery VARCHAR(2000)  
    SELECT  @cols = STUFF(( SELECT distinct  '], [' +cast([Section] as varchar)
                            FROM dbo.SchoolData FOR XML PATH('') ), 1, 2, '') + ']'  
    SET @sqlquery = 'SELECT * into ##a FROM  
          (SELECT ID=1,z.Section,z.IRI1  
           FROM dbo.SchoolData z) base  
           PIVOT (Max(IRI1) FOR [Section] IN (' + @cols + ')) AS finalpivot'  
    SET @sqlquery2 = 'SELECT * into ##b FROM  
          (SELECT ID=1,z.Section,z.IRI2  
           FROM dbo.SchoolData z) base  
           PIVOT (Max(IRI2) FOR [Section] IN (' + @cols + ')) AS finalpivot'  
    SET @sqlquery3 = 'SELECT * into ##c FROM  
          (SELECT ID=1,z.Section,z.RUT  
           FROM dbo.SchoolData z) base  
           PIVOT (Max(RUT) FOR [Section] IN (' + @cols + ')) AS finalpivot'  
    SET @sqlquery4 = 'SELECT * into ##d FROM  
          (SELECT ID=1,z.Section,z.RN1  
           FROM dbo.SchoolData z) base  
           PIVOT (Max(RN1) FOR [Section] IN (' + @cols + ')) AS finalpivot'  
    SET @sqlquery5 = 'SELECT * into ##e FROM  
          (SELECT ID=1,z.Section,z.RN2  
           FROM dbo.SchoolData z) base  
           PIVOT (Max(RN2) FOR [Section] IN (' + @cols + ')) AS finalpivot'  
    Execute(@sqlQuery)  
    Execute(@sqlQuery2)  
    Execute(@sqlQuery3)  
    Execute(@sqlQuery4)  
    Execute(@sqlQuery5)  
    
    
    
    Select * from ##a a join ##b b on a.ID=b.ID join ##c c on a.ID=c.ID join ##d d on a.ID=d.ID join ##e e on a.ID=e.ID  
    drop table ##a  
    drop table ##b  
    drop table ##c  
    drop table ##d  
    drop table ##e  
    
    • 0

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve