【问题标题】:SQL Pivot to Generate Dynamic ColumnsSQL Pivot 生成动态列
【发布时间】:2021-12-29 17:32:20
【问题描述】:

我有以下数据:

我有以下代码:


select * from
(
SELECT 
d.CreatedDate,
m.siteid,
m.ProjectNum



FROM DWCorp.SSMaster m 
INNER JOIN DWCorp.SSDetail d ON d.MasterId = m.Id WHERE  ActionId = 7
)as Sourcetable
pivot
(
max(createddate)
for siteid in ([1],[2],[3],[4],[5])
) As pivottable 

我希望数据看起来像这样:

最多只能有 5 个日期。我现在拥有它的方式是按我不想要的站点来旋转它。我希望它按日期旋转。

有人可以帮忙吗?我知道我可能需要使用动态 SQL,但不知道该怎么做。我已经搜索了论坛,但没有得到我要找的东西。

文本输出:

CreatedDate               siteid ProjectNum
2021-04-06 13:14:01.8933333 20  OTHO00006
2021-04-28 16:40:01.9066667 20  OTHO00006
2021-05-03 22:47:01.7466667 20  OTHO00006
2021-04-28 16:42:02.3700000 20  OTHO00016
2021-05-06 13:27:01.9633333 20  OTHO00016
2021-05-27 15:10:01.7066667 20  OTHO00018
2021-06-29 13:01:01.9266667 20  OTHO00024
2021-05-12 13:38:01.8300000 20  OTHO00024
2021-06-29 13:02:04.7800000 20  OTHO00028
2021-03-25 13:00:03.6100000 21  OBEL00001
2021-08-10 19:44:01.9233333 21  OBEL00003
2021-11-03 20:45:39.2733333 21  OBEL00003
2021-04-26 18:57:34.5533333 21  OBEL00004

【问题讨论】:

  • pivot 命令依赖于 rdbms。你的是什么?
  • SQL 服务器版本 2012
  • 您能否以文本而不是图像的形式分享您的示例数据?
  • 添加了文本输出。
  • @HimanshuAhuja OP 声明最多有 5 个日期,必须相信 OP 知道他自己的数据。

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


【解决方案1】:

试试这个,但我希望这只是一个示例用例,因为动态用例可能有 365 天/日期

   With dtes as (
  Select distinct trim(createdDate), row_number() over (order by 
   1) rn 
  From  DWCorp.SSMaster m 
  INNER JOIN DWCorp.SSDetail d ON d.MasterId = m.Id WHERE  
  ActionId = 7 )

    SELECT 
    m.ProjectNum, 
  
     Max(case when trim(createddate) = Select 
    trim(createdDate) from dtes where rn=1 then m.siteid end), 
    Max(case when trim(createddate) = Select 
    trim(createdDate) from dtes where rn=2 then m.siteid end)
     Max(case when trim(createddate)= Select 
    trim(createdDate) from dtes where rn=3 then m.siteid end),
    Max(case when trim(createddate)= Select 
    trim(createdDate) from dtes where rn=4 then m.siteid end),
    
       Max(case when trim(createddate)= Select 
    trim(createdDate) from dtes where rn=5 then m.siteid end)
    
  FROM DWCorp.SSMaster m 
 INNER JOIN DWCorp.SSDetail d ON d.MasterId = m.Id WHERE  
 ActionId = 7 
  group by project_num
 
  
 

【讨论】:

  • 感谢大家的帮助。解决了我的问题。像往常一样很棒的论坛。
【解决方案2】:

您可以利用row_number 窗口函数和条件案例聚合来做到这一点:

with c as (
    select Convert(date,CreatedDate) CreatedDate, ProjectNum,
      Row_Number() over (partition by ProjectNum order by createddate) col
    from t
)
select 
    ProjectNum,
    max(case when col=1 then CreatedDate end) Date1,
    max(case when col=2 then CreatedDate end) Date2,
    max(case when col=3 then CreatedDate end) Date3,
    max(case when col=4 then CreatedDate end) Date4,
    max(case when col=5 then CreatedDate end) Date5
from c
group by ProjectNum

【讨论】:

    【解决方案3】:

    这样的事情可以解决问题:

    select projectNum, 
      [1] as Date1,
      [2] as Date2,
      [3] as Date3,
      [4] as Date4,
      [5] as Date5
    from (
      select d.projectNum, d.createdDate, d.dateId
      from (
        select dd.rn as dateId, dd.createdDate, dd.projectNum
        from (
          select *, row_number() over (partition by projectNum order by createdDate asc) rn
          from your_data
          ) dd
        where rn <= 5
        -- order by 3, 1
        ) d
      ) as src
      pivot (
        max(createdDate)
        for dateId in ([1],[2],[3],[4],[5])
      ) as pvt
    

    为了更容易并避免使用动态 sql,您可以使用 row_number 为从最旧到最新排序的每个日期分配一个 dateId,然后使用此 id 来透视数据。

    【讨论】:

      猜你喜欢
      • 2014-11-26
      • 1970-01-01
      • 2014-11-27
      • 2016-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-07
      • 1970-01-01
      相关资源
      最近更新 更多