Поведение функции LAG в первом ряду и группе повторяющихся разделов - PullRequest
0 голосов
/ 02 октября 2018

Я пытаюсь использовать функцию LAG () в MSSQL, и у меня странное поведение.Таблица выглядит следующим образом:

    ID  TotalReadings    Month     Device
0    1    4           January         M  
1    1    4           January         D  
2    1    4           January         T  
2    1    4           January         L  
2    1    2           February        M  
2    1    2           February        D  
2    1    2           February        L  
0    1    2           February        T  
1    1    6           March           M  
2    1    6           March           D  
2    1    6           March           L  
2    1    6           March           T  
2    1    6           April           M  
2    1    6           April           D  
2    1    6           April           T  
2    1    6           April           L  

То, что я сделал, было:

Select *,
    CASE 
        WHEN 
             ISNULL(LAG(TotalReadings) OVER (PARTITION BY ID ORDER BY Month ), 0) < TotalReadings THEN 'Increase' 
        WHEN
             ISNULL(LAG(TotalReadings) OVER (PARTITION BY ID ORDER BY Month), 0) = TotalReadings THEN 'Neutral'
        WHEN
             ISNULL(LAG(TotalReadings) OVER (PARTITION BY ID ORDER BY Month), 0) > TotalReadings THEN 'Decrease'
    END As Trend 
from table

и получил:

    ID  TotalReadings    Month     Device   Trend
0    1    4           January         M      Increase
1    1    4           January         D      Neutral
2    1    4           January         T      Neutral
2    1    4           January         L      Neutral
2    1    2           February        M      Decrease
2    1    2           February        D      Neutral
2    1    2           February        L      Neutral
0    1    2           February        T      Neutral
1    1    6           March           M      Increase
2    1    6           March           D      Neutral
2    1    6           March           L      Neutral
2    1    6           March           T      Neutral
2    1    6           April           M      Neutral
2    1    6           April           D      Neutral
2    1    6           April           T      Neutral
2    1    6           April           L      Neutral

Но я действительно хочу, чтобы сначалагруппирование по месяцам с трендом с именем «Start», поскольку нет предыдущего значения для сравнения, а остальные должны учитывать аналогичные TOtalReadings, которые в месячном выражении одинаковы, поэтому тренд не должен быть правильным только для первой строки в началеновая строка месяца, но для всех: как это:

    ID  TotalReadings    Month     Device   Trend
0    1    4           January         M      Start
1    1    4           January         D      Start
2    1    4           January         T      Start
2    1    4           January         L      Start
2    1    2           February        M      Decrease
2    1    2           February        D      Decrease
2    1    2           February        L      Decrease
0    1    2           February        T      Decrease
1    1    6           March           M      Increase
2    1    6           March           D      Increase
2    1    6           March           L      Increase
2    1    6           March           T      Increase
2    1    6           April           M      Neutral
2    1    6           April           D      Neutral
2    1    6           April           T      Neutral
2    1    6           April           L      Neutral

любая подсказка?

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Если вы добавите столбец identity, то вы можете использовать этот код

create table #order ( i int identity(1,1),  ID  int, TotalReadings    int, Month     varchar(20), Device varchar(1))
insert #order values
(  1  ,  4           ,'January'         ,'M' ) 
,(  1  ,  4           ,'January'         ,'D' ) 
,(  1  ,  4           ,'January'         ,'T' ) 
,(  1  ,  4           ,'January'         ,'L' ) 
,(  1  ,  2           ,'February'       ,'M'  )
,(  1  ,  2           ,'February'       ,'D'  )
,(  1  ,  2           ,'February'       ,'L'  )
,(  1  ,  2           ,'February'       ,'T'  )
,(  1  ,  6           ,'March'           ,'M' ) 
,(  1  ,  6           ,'March'           ,'D' ) 
,(  1  ,  6           ,'March'           ,'L' ) 
,(  1  ,  6           ,'March'           ,'T' ) 
,(  1  ,  6           ,'April'           ,'M' ) 
,(  1  ,  6           ,'April'           ,'D' ) 
,(  1  ,  6           ,'April'           ,'T' ) 
,(  1  ,  6           ,'April'           ,'L' )

Select *
    ,CASE 
        WHEN 
             lag(TotalReadings, 4) OVER (PARTITION BY ID ORDER BY i,id, Month)  < TotalReadings THEN 'Increase' 
        WHEN                                                                   
             lag(TotalReadings, 4) OVER (PARTITION BY ID ORDER BY i,id, Month)  = TotalReadings THEN 'Neutral'
        WHEN                                                                   
             lag(TotalReadings, 4) OVER (PARTITION BY ID ORDER BY i,id, Month)  > TotalReadings THEN 'Decrease'
        WHEN                                                                   
             lag(TotalReadings, 4) OVER (PARTITION BY ID ORDER BY i,id, Month)  is null THEN 'start'
    END As Trend 
from #order
order by i

Редактировать 1: НЕТ НЕОБХОДИМОСТИ КОЛОННЫ ИДЕНТИЧНОСТИ

Select *
    ,CASE 
        WHEN 
             lag(TotalReadings, 4) OVER (PARTITION BY ID ORDER BY id, MONTH(MONTH + ' 1 2014') )  < TotalReadings THEN 'Increase' 
        WHEN                                                         
             lag(TotalReadings, 4) OVER (PARTITION BY ID ORDER BY id, MONTH(Month + ' 1 2014') )  = TotalReadings THEN 'Neutral'
        WHEN                                                         
             lag(TotalReadings, 4) OVER (PARTITION BY ID ORDER BY id, MONTH(Month + ' 1 2014') )  > TotalReadings THEN 'Decrease'
        WHEN                                                          
             lag(TotalReadings, 4) OVER (PARTITION BY ID ORDER BY id, MONTH(Month + ' 1 2014') )  is null THEN 'start'
    END As Trend 
from #order
order by MONTH(Month + ' 1 2014') 
0 голосов
/ 02 октября 2018

Вот, пожалуйста:

    create table #t
    (id int, totalreadings int, month int, device char(1))

    insert into #t
    values
    (1,4,1,'M'),
    (1,4,1,'D'),
    (1,4,1,'T'),
    (1,4,1,'L'),
    (1,2,2,'M'),
    (1,2,2,'D'),
    (1,2,2,'L'),
    (1,2,2,'T'),
    (1,6,3,'M'),
    (1,6,3,'D'),
    (1,6,3,'L'),
    (1,6,3,'T'),
    (1,6,4,'M'),
    (1,6,4,'D'),
    (1,6,4,'L'),
    (1,6,4,'T')


    Select *,
        CASE 
            WHEN 
                 LAG(TotalReadings) OVER (PARTITION BY ID,device ORDER BY Month ) < TotalReadings THEN 'Increase' 
            WHEN
                 LAG(TotalReadings) OVER (PARTITION BY ID,device ORDER BY Month) = TotalReadings THEN 'Neutral'
            WHEN
                 LAG(TotalReadings) OVER (PARTITION BY ID,device ORDER BY Month) > TotalReadings THEN 'Decrease'
            ELSE 'Start'
        END As Trend 
    from #t
    order by month

id  totalreadings   month   device  Trend
1   4   1   D   Start
1   4   1   L   Start
1   4   1   M   Start
1   4   1   T   Start
1   2   2   T   Decrease
1   2   2   M   Decrease
1   2   2   L   Decrease
1   2   2   D   Decrease
1   6   3   D   Increase
1   6   3   L   Increase
1   6   3   M   Increase
1   6   3   T   Increase
1   6   4   T   Neutral
1   6   4   M   Neutral
1   6   4   L   Neutral
1   6   4   D   Neutral
...