使用sqlserver根据时间段获取不同的MO
Posted
技术标签:
【中文标题】使用sqlserver根据时间段获取不同的MO【英文标题】:Use sqlserver to get different MO according to time period 【发布时间】:2020-09-19 12:49:31 【问题描述】:。
源表route
:
CREATE TABLE [dbo].route(
[sfcno] varchar(20) NOT NULL,
[time] [datetime]NOT NULL
) ON [PRIMARY]
GO
insert into route(sfcno ,time)
values (10,'08:00'),
(10,'08:10'),
(11,'08:30'),
(22,'09:10'),
(33,'10:10'),
(44,'11:10'),
(555,'11:30')
我想得到以下内容
08:00-09:00 09:00-10:00 10:00-11:00 11:00-12:00
10,11 22 33 44,555
【问题讨论】:
【参考方案1】:我发现将结果放在行中比放在列中更有意义:
select
format(datepart(hour, time), '00') + ':00-'
+ format(datepart(hour, time) + 1, '00') + ':00' as timeslot,
string_agg(sfcno, ',') within group(order by sfcno) sfcnos
from route
group by datepart(hour, time)
时隙 | sfcnos
:------------ | :--------
08:00-09:00 | 10,10,11
09:00-10:00 | 22
10:00-11:00 | 33
11:00-12:00 | 44,555
如果你真的想要列,那么你需要条件聚合 - 输入时间会更长:
select
string_agg(case when datepart(hour, time) = 8 then sfcno end, ',') within group(order by sfcno) as time_slot_08_09,
string_agg(case when datepart(hour, time) = 9 then sfcno end, ',') within group(order by sfcno) as time_slot_09_10,
string_agg(case when datepart(hour, time) = 10 then sfcno end, ',') within group(order by sfcno) as time_slot_10_11,
string_agg(case when datepart(hour, time) = 11 then sfcno end, ',') within group(order by sfcno) as time_slot_11_12
from route
time_slot_08_09 | time_slot_09_10 | time_slot_10_11 | time_slot_11_12
:---------------- | :---------------- | :---------------- | :--------------
10,10,11 | 22 | 33 | 44,555
Demo on DB Fiddle
【讨论】:
谢谢,但我需要不同的 sfcno。如果你有更好的答案,你能告诉我吗?【参考方案2】:您想要得到的是由于定义的规则而将行转换为列的旋转。更喜欢使用动态旋转,如下图所示:
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX)
SELECT @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(
CONCAT(
FORMAT(DATEPART(hour, time), '00') + ':00',
'-',
FORMAT(DATEPART(hour, time) + 1, '00') + ':00'
)
) AS time
FROM route
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET @query =
N'SELECT '+ @cols + N'
FROM
(
SELECT STRING_AGG(sfcno, '','') WITHIN GROUP (ORDER BY sfcno) AS sfcno, time
FROM ( SELECT DISTINCT sfcno,
CONCAT(
FORMAT(DATEPART(hour, time), ''00'') + '':00-'',
FORMAT(DATEPART(hour, time) + 1, ''00'') + '':00''
) AS time
FROM route ) r
GROUP BY time
) q
PIVOT
(
MAX(sfcno) FOR time IN (' + @cols + N')
) p '
EXEC sp_executesql @query;
Demo
【讨论】:
不好意思,我的sqlserver版本是2012以上是关于使用sqlserver根据时间段获取不同的MO的主要内容,如果未能解决你的问题,请参考以下文章