我正在尝试使用select语句来创建视图,将具有datetime的表转换为每行中包含记录的表,以及按时间(按站分区)的连续值的开始结束时间;记录'字段不是0.
以下是初始表的示例。
转置后它应该是什么样子。
有人可以帮忙吗?
答案 0 :(得分:1)
ROW_NUMBER()是分区的最佳选择。接下来,您可以在分区表上进行自联接,以查看时间之间的差异是否大于五分钟。我认为最好的解决方案是根据您的模式对时间戳差异的滚动总和进行分区,偏移5分钟。如果五分钟不是常规模式,则可能存在可与零一起使用的通用方法。
下面以CTE编写的解决方案,以便轻松创建视图(虽然这是一个缓慢的视图)。
WITH partitioned as (
SELECT datetime, station, recording,
ROW_NUMBER() OVER(PARTITION BY station
ORDER BY datetime ASC) rn
FROM table --Not sure what the tablename is
WHERE recording != 0),
diffed as (
SELECT a.datetime, a.station,
DATEDIFF(mi,ISNULL(b.datetime,a.datetime),a.datetime)-5) Difference
--The ISNULL logic is for when a.datetime is the beginning of the block,
--we want a 0
FROM partitioned a
LEFT JOIN partitioned b on a.rn = b.rn + 1 and a.station=b.station
GROUP BY a.datetime,a.station),
cumulative as (
SELECT a.datetime, a.station, SUM(b.difference) offset_grouping
FROM diff a
LEFT JOIN diff b on a.datetime >= b.datetime and a.station = b.station ),
ordered as (SELECT datetime,station,
ROW_NUMBER() OVER(PARTITION BY station,offset_grouping ORDER BY datetime asc) starter,
ROW_NUMBER() OVER(PARTITION BY station,offset_grouping ORDER BY datetime desc) ender
FROM cumulative)
SELECT ROW_NUMBER() OVER(ORDER BY a.datetime) unique_id,a.station,a.datetime startdate, b.datetime enddate
FROM ordered a
JOIN ordered b on a.starter = b.ender and a.station=b.station and a.starter=1
这是我能想到的唯一解决方案,但是根据您拥有的数据量,它很慢。
答案 1 :(得分:1)
您可以使用conditional_change_event
分析函数创建一个特殊的分组标识符,以便在简单查询中将其拆分出来:
select row_number() over () unique_id,
station,
min(datetime) startdate,
max(datetime) enddate
from (
select t.*, CONDITIONAL_CHANGE_EVENT(decode(recording,0,0,1))
over (partition by station order by datetime) chg
from mytable t
) x
where recording > 0
group by station, chg
order by 1, 2
解码只是设置你的岛屿和间隙(其中间隙记录< = 0且岛屿记录> 0)。然后,对其的更改事件将生成用于分组的新标识符。另请注意,我正在对change事件进行分组,即使它不是输出的一部分。