根据条件将一列转换为两列

lvjbypge  于 2021-07-24  发布在  Java
关注(0)|答案(3)|浏览(322)

我有一张这样的table:

TagName          DateTime        value
HA_06_ON    2020-07-07 08:52:14    1
HA_06_ON    2020-07-07 09:01:42    0
HA_06_ON    2020-07-07 09:02:17    1
HA_06_ON    2020-07-07 09:32:55    0
HA_06_ON    2020-07-07 09:33:21    1
HA_06_ON    2020-07-07 09:35:02    0
HA_06_ON    2020-07-07 09:35:27    1 
HA_06_ON    2020-07-07 09:35:44    0
HA_06_ON    2020-07-07 10:10:32    1
HA_06_ON    2020-07-07 10:10:40    0

我想根据值(value=1==>starttime,value=0==>endtime)将这个表转换成这个基表。

TagName        StartTime                EndTime
HA_06_ON   2020-07-07 08:52:14      2020-07-07 09:01:42
HA_06_ON   2020-07-07 09:02:17      2020-07-07 09:32:55
....

我曾尝试在select语句上使用case when,但像这样在每一列上返回null

TagName           StartTime            EndTime
HA_06_ON      2020-07-07 08:57:07       NULL
HA_06_ON            NULL        2020-07-07 09:01:42
HA_06_ON      2020-07-07 09:02:17       NULL
HA_06_ON            NULL        2020-07-07 09:32:55
HA_06_ON      2020-07-07 09:33:21       NULL
HA_06_ON            NULL        2020-07-07 09:35:02
35g0bw71

35g0bw711#

就因为我没看到 sum() over 选项
例子

Select TagName
      ,StartTime = min(DateTime)
      ,EndTime   = max(DateTime)
 From ( 
        Select *
              ,Grp = sum(value) over (partition by TagName order by DateTime) 
         From @YourTable
      ) A
 Group By TagName,Grp

退货

TagName     StartTime                   EndTime
HA_06_ON    2020-07-07 08:52:14.000     2020-07-07 09:01:42.000
HA_06_ON    2020-07-07 09:02:17.000     2020-07-07 09:32:55.000
HA_06_ON    2020-07-07 09:33:21.000     2020-07-07 09:35:02.000
HA_06_ON    2020-07-07 09:35:27.000     2020-07-07 09:35:44.000
HA_06_ON    2020-07-07 10:10:32.000     2020-07-07 10:10:40.000
6ovsh4lw

6ovsh4lw2#

因为这里没有分组列,所以我们必须做一个假设:我们可以处理您的数据,假设如果按日期排序,1和0将交替。否则就没有解决方案,因为我们不知道如何关联1和0。
既然我们可以假设这个顺序,我们可以使用 lag() 或者 lead() 做这个。注意,这假设您从1开始,并且每个1都有一个对应的0。如果最后一个1没有对应的0,则该行的endtime将为空。

select  u.TagName, 
        u.StartTime, 
        u.EndTime 
from    (
        select  TagName, 
                StartTime = [DateTime] ,
                EndTime   = lead([DateTime], 1) over
                            (
                                partition by TagName
                                order by [Datetime] asc
                            ), 
                value 
        from t
        ) u
where   u.value = 1
sbtkgmzw

sbtkgmzw3#

有多种方法可以解决这个问题。如果我假设值是完全交错的,一种方法是聚合:

select tagname, min(datetime) as starttime, max(datetime) as endtime
from (select t.*,
             row_number() over (partition by tagname, value order by datetime) as seqnum
      from t
     ) t
group by tagname, seqnum;

相关问题