SQL 旋转以生成动态列
SQL Pivot to Generate Dynamic Columns
我有以下数据:
我有以下代码:
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
像这样的东西可以解决问题:
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 来旋转数据。
您可以利用 row_number
window 函数和 条件案例 聚合来做到这一点:
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
试试这个,但我希望这只是一个示例用例,因为动态用例可能有 365 个 days/dates
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
我有以下数据:
我有以下代码:
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
像这样的东西可以解决问题:
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 来旋转数据。
您可以利用 row_number
window 函数和 条件案例 聚合来做到这一点:
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
试试这个,但我希望这只是一个示例用例,因为动态用例可能有 365 个 days/dates
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