【问题标题】:Sql Pivot table with three cross tab and multiple columns dynamically具有三个交叉表和多列动态的 Sql Pivot 表
【发布时间】:2021-01-15 07:12:34
【问题描述】:

我有下表,其值为

CREATE TABLE stud 
  ( 
     sname NVARCHAR(10), 
     hr    NVARCHAR(30), 
     dt    DATETIME, 
     att   VARCHAR(3) 
  )

INSERT INTO stud VALUES ('Abi',  '1',  '21/01/2013','a')
INSERT INTO stud VALUES ('Abi',  '2',  '21/01/2013','p')
INSERT INTO stud VALUES ('bala',  '1',  '21/01/2013','p')
INSERT INTO stud VALUES ('bala',  '2',  '21/01/2013','a')
INSERT INTO stud VALUES ('bala',  '1',  '22/01/2013','od')
INSERT INTO stud VALUES ('bala',  '2',  '22/01/2013','ml')
INSERT INTO stud VALUES ('Abi',  '1',  '22/01/2013','ml')
INSERT INTO stud VALUES ('Abi',  '2',  '22/01/2013','od')

如果我选择这个表,我会得到输出

SELECT * 
FROM   stud 
sname hr dt att
阿比 1 2013-01-21 00:00:00.000
阿比 2 2013-01-21 00:00:00.000 p
巴拉 1 2013-01-21 00:00:00.000 p
巴拉 2 2013-01-21 00:00:00.000 一
巴拉 1 2013-01-22 00:00:00.000 od
巴拉 2 2013-01-22 00:00:00.000 毫升
阿比 1 2013-01-22 00:00:00.000 毫升
Abi 2 2013-01-22 00:00:00.000 od

但我希望在 ASP.NET 中的水晶报告中输出如下(注意:日期应该像 from_dateto_date 一样动态给出)

sname 21/01/2013 22/01/2013

我在漫长的日子里尝试了这个输出,但没有得到输出。

【问题讨论】:

  • 你用的是什么 rdbms?
  • @bluefeet 我不得不从NVARCHAR猜测MSSQL

标签: sql pivot


【解决方案1】:

如果您使用的是 SQL Server 2005+,则可以通过多种方式应用 PIVOT 函数。

您可以以静态枢轴的形式对值进行硬编码:

select *
from
(
  select sname, 
    'hour_no_'+hr+'_'+convert(nvarchar(10), dt, 120) dt,
    att
  from stud
) st
pivot
(
  max(att)
  for dt in ([hour_no_1_2013-01-21], [hour_no_2_2013-01-21],
             [hour_no_1_2013-01-22], [hour_no_2_2013-01-22])
) piv

SQL Fiddle with Demo

或者您可以使用动态 sql 在运行时生成 sql 语句。查询的动态版本是:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols 
  = STUFF((SELECT ', ' + QUOTENAME('Hour_No_'+hr+'_'++convert(nvarchar(10), dt, 120)) 
           from stud
           group by hr, dt
           order by dt, hr
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT sname,' + @cols + ' from 
             (
                select sname, 
                  ''hour_no_''+hr+''_''+convert(nvarchar(10), dt, 120) dt,
                  att
                from stud
            ) x
            pivot 
            (
                max(att)
                for dt in (' + @cols + ')
            ) p '

execute(@query)

SQL Fiddle with Demo

两者都给出结果:

| SNAME | HOUR_NO_1_2013-01-21 | HOUR_NO_2_2013-01-21 | HOUR_NO_1_2013-01-22 | HOUR_NO_2_2013-01-22 |
-----------------------------------------------------------------------------------------------------
|   Abi |                    a |                    p |                   ml |                   od |
|  bala |                    p |                    a |                   od |                   ml |

【讨论】:

  • @user1999109 欢迎您。如果此答案或对您问题的任何答案有帮助,请务必通过其左侧的复选标记接受它。它将帮助未来的访问者,您将获得网站代表接受。
猜你喜欢
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 2019-08-26
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
  • 2020-11-28
  • 1970-01-01
相关资源
最近更新 更多