【问题标题】:change row data to column with out using Pivot function in SQL Server 2012在 SQL Server 2012 中使用 Pivot 函数将行数据更改为列
【发布时间】:2021-10-29 07:29:39
【问题描述】:

我正在尝试透视表数据

    Create table strategy(date date,[event] varchar(100),eType varchar(100))
    insert into  dbo.strategy (DATE, [event], eType) values
    ('1 Jan 2018' , 'ABZPD', 'dev'),
    ('1 Jan 2018', 'BFSPD', 'stage'),
    ('1 Jan 2018', 'BFSPD', 'pre-dep');


select * from strategy

预期输出:

DATE ABZPD BFSPD BFSZH BHXPD BHXZH BRSZH BRUPQ
2018-01-01 dev stage NULL NULL NULL NULL NULL
2018-01-01 NULL pre-dep NULL NULL NULL NULL NULL

我尝试了以下代码

SELECT * 
FROM  
(
  SELECT DATE
               ,[event]
               ,eType 
          FROM  [strategy] 
          where datename(year, DATE) = 2018 or datename(year,DATE)=2019
) AS SourceTable  
PIVOT  
(  
  MAX(eType)
          FOR event  IN ([ABZPD],[BFSPD]
,[BFSZH]
,[BHXPD]
,[BHXZH]
,[BRSZH]
,[BRUPQ] )  
) AS PivotTable;  



drop table strategy

下面是我得到的输出:

DATE ABZPD BFSPD BFSZH BHXPD BHXZH BRSZH BRUPQ
2018-01-01 dev stage NULL NULL NULL NULL NULL

【问题讨论】:

  • 为什么dev属于第一条记录而不属于第二条记录?这就是为什么你没有得到你所期望的,因为 pivot 使用隐式聚合工作,你不能在同一日期有 2 个最大值

标签: sql sql-server tsql sql-server-2012 pivot


【解决方案1】:

您可以通过在查询中添加 ROW_NUMBER 来实现这一点,但无论如何 - 您选择 MAX(etype),因此您显示的结果是正确的...您希望通过查询实现什么?预期的结果看起来有点奇怪......但是,以 Rownumber 为例:

DECLARE @strategy TABLE(date date,[event] varchar(100),eType varchar(100))

insert into  @strategy (DATE, [event], eType) values
('1 Jan 2018' , 'ABZPD', 'dev'),
('1 Jan 2018', 'BFSPD', 'stage'),
('1 Jan 2018', 'BFSPD', 'pre-dep');


WITH cteStrategy AS(
SELECT *, ROW_NUMBER() OVER (PARTITION BY date, event ORDER BY eType) rn
  FROM @strategy
)
SELECT * 
FROM  
(
  SELECT DATE
               ,[event]
               ,eType 
               ,rn
          FROM  cteStrategy 
          where datename(year, DATE) = 2018 or datename(year,DATE)=2019
) AS SourceTable  
PIVOT  
(  
  MAX(eType)
          FOR event  IN ([ABZPD],[BFSPD]
,[BFSZH]
,[BHXPD]
,[BHXZH]
,[BRSZH]
,[BRUPQ] )  
) AS PivotTable; 

【讨论】:

    【解决方案2】:

    我建议将查询编写为:

    select date,
           max(case when event = 'ABZPD' then eType end) as ABZPD,
           max(case when event = 'BFSPD' then eType end) as BFSPD,
           max(case when event = 'BFSZH' then eType end) as BFSZH,
           max(case when event = 'BHXPD' then eType end) as BHXPD,
           max(case when event = 'BHXZH' then eType end) as BHXZH,
           max(case when event = 'BRUPQ' then eType end) as BRUPQ
    from (select s.*,
                 row_number() over (partition by date order by date) as seqnum
          from strategy s
          where date >= '2018-01-01' and date < '2020-01-01'
         ) s
    group by date, seqnum;
    

    请特别注意对日期过滤方式的更改。 datename() 返回一个字符串,您正在将该字符串与一个数字进行比较。不要混合数据类型!无论如何,日期范围通常更适合字符串比较。

    我更喜欢条件聚合而不是定制的pivot 功能,因为聚合更加灵活。

    【讨论】:

      猜你喜欢
      • 2016-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多