获取每个列值的计数

问题描述 投票:1回答:2

输入

Create Table #t1 (CaseId Int, NewValue  char(2),Attribute char(2),TimeStamp datetime)  

insert into #t1 values
(1,      'A',         'X'   ,       '2020-01-01 13:01'),
(1,      'Au',        'WB' ,        '2020-01-01 13:02'),   
(1 ,     'C'  ,       'P'   ,       '2020-01-01 13:03'),
(1 ,     'Ma',        'WB' ,        '2020-01-01 13:04'),
(1 ,     'C'   ,      'D',          '2020-01-01 13:05'), 
(1,      'D'  ,       'E',          '2020-01-01 13:04'),
(2 ,     'M'  ,       'P' ,         '2020-05-01 15:20'),
(2 ,     'X'  ,       'WB' ,        '2020-05-01 15:26'),
(2  ,    'Y' ,        'WB',         '2020-05-01 15:29'), 
(2  ,    'X'  ,       'P'  ,         '2020-05-01 15:31')

我需要如下输出。

CaseId  NewValue    Attribute   TimeStamp   NewColumn   NewColumn   Count
1        A            X         01:00.0         NULL    NULL         0
1        Au           WB        02:00.0         Au-WB   Au-WB        2
1        C            P         03:00.0         Au-WB   Au-WB        2
1        Ma           WB        04:00.0         Ma-WB   Ma-WB        3
1        C            D         05:00.0         Ma-WB   Ma-WB        3
1        D            E         04:00.0         Ma-WB   Ma-WB        3
2        M            P         20:00.0         NULL    NULL         0
2        X            WB        26:00.0         X -WB   X -WB        1
2        Y            WB        29:00.0         Y -WB   Y -WB        2
2        X            P         31:00.0         Y -WB   Y -WB        2

松鼠帮助减少了一切。查询如下。有人知道如何获得该计数吗?

select  *, wb.NewColumn
from    #t1 t
        outer apply
        (
            select top 1 x.NewValue + '-' + x.Attibute as NewColumn
            from    #t1 x
            where   x.CaseId    = t.CaseId
            and     x.TimeStamp <= t.TimeStamp
            and     x.Attibute  = 'WB'
            order by x.TimeStamp desc
        ) wb
sql sql-server tsql gaps-and-islands
2个回答
0
投票

这[[looks就像是一个空白和孤岛的问题,每次遇到带有Attribute 'WB'的记录时,都会创建一个新岛。

如果是这样,这是使用窗口函数解决它的一种方法:

select caseId, newValue, attribute, timeStamp, case when grp > 0 then first_value(newValue) over(partition by caseId, grp order by timeStamp) + '-' + first_value(attribute) over(partition by caseId, grp order by timeStamp) end newValue, case when grp > 0 then count(*) over(partition by caseId, grp) else 0 end cnt from ( select t.*, sum(case when attribute = 'WB' then 1 else 0 end) over(partition by caseId order by timeStamp) grp from #t1 t ) t order by caseId, timeStamp

内部查询执行一个窗口sum()来定义组:对于给定的attribute,每次满足'WB' caseId时,就会开始一个新的组。然后,外部查询使用first_value()恢复组中的第一个值,并执行窗口count()以计算每个组的记录数。它包装在条件逻辑中,因此在满足第一个'WB'属性之前,不会填充其他列。

Demo on DB Fiddle

caseId | newValue |属性|时间戳记| newValue |碳纳米管-----:| :------- | :-------- | :---------------------- | :------- | -:1 | A | X | 2020-01-01 13:01:00.000 |
| 01 |金| WB | 2020-01-01 13:02:00.000 | Au-WB | 21 | C | P | 2020-01-01 13:03:00.000 | Au-WB | 21 |妈WB | 2020-01-01 13:04:00.000 | Ma-WB | 31 | D | E | 2020-01-01 13:04:00.000 | Ma-WB | 31 | C | D | 2020-01-01 13:05:00.000 | Ma-WB | 32 | M | P | 2020-05-01 15:20:00.000 | | 02 | X | WB | 2020-05-01 15:26:00.000 | X -WB | 1个2 | Y | WB | 2020-05-01 15:29:00.000 | Y-WB | 22 | X | P | 2020-05-01 15:31:00.000 | Y-WB | 2

0
投票
Bro,

上面的查询效果很好,但是,如果存在另一个具有相同时间戳的记录,则无法给出正确的结果。范例

插入#t1值(1,'A','X','2020-01-01 13:01'),(1,'C','P','2020-01-01 13:02'),(1,'Au','WB','2020-01-01 13:02'),(1,'C','P','2020-01-01 13:03'),(1,'Ma','WB','2020-01-01 13:04'),(1,'C','D','2020-01-01 13:05'),(1,'D','E','2020-01-01 13:04'),(2,'M','P','2020-05-01 15:20'),(2,'X','WB','2020-05-01 15:26'),(2,'Y','WB','2020-05-01 15:29'),(2,'X','P','2020-05-01 15:31')

© www.soinside.com 2019 - 2024. All rights reserved.