как группировать данные после каждого изменения, но не объединять группу, даже если в следующий раз значение повторится в sql - PullRequest
0 голосов
/ 07 ноября 2019

Я должен сгруппировать данные на основе столбца суммы, но если сумма повторится через некоторый интервал, тогда это должно рассматриваться как новая группа. Например,

CREATE TABLE [dbo].[TEST](
    [ID] [INT] NULL,
    [DLRCODE] [VARCHAR](20) NULL,
    [AMN] [DECIMAL](21, 5) NULL,
    [RATE] [DECIMAL](7, 5) NULL,
    [DTE] [DATETIME] NULL
) ON [NFS_DATA]

----- это должнобыть первой группой

1   123 10.00000    5.00000 2019-11-01 00:00:00.000
2   123 10.00000    5.00000 2019-11-02 00:00:00.000
3   123 10.00000    5.00000 2019-11-03 00:00:00.000
-----this should be second group
4   123 15.00000    5.00000 2019-11-04 00:00:00.000
-----this should be third group
5   123 10.00000    5.00000 2019-11-05 00:00:00.000
6   123 10.00000    5.00000 2019-11-06 00:00:00.000
-----this should be fourth group
7   123 20.00000    5.00000 2019-11-07 15:02:07.537

, как вы можете проверить из приведенного выше кода и данных, результат должен быть группой, при каждом изменении суммы будет создаваться новая группа.

результат понравится

1 30  --- group of first three records
2 15  --- group of fourth records
3 20  --- group of  fifth and sixth records
4 20  --- group of seven record

Ответы [ 2 ]

2 голосов
/ 07 ноября 2019

Это можно сделать с помощью комбинации LAG и условного агрегирования:

WITH CTE AS
(
    SELECT Id
        , DLRCode
        , Amn
        , Rate
        , DTE
        , ISNULL(LAG(Amn) OVER(ORDER BY DTE), Amn) As PreviousAmount
    FROM dbo.Test
)

SELECT  Id
        , DLRCode
        , Amn
        , Rate
        , DTE
        , SUM(IIF(Amn = PreviousAmount, 0, 1)) OVER(ORDER BY DTE) As Grp
FROM CTE        
0 голосов
/ 07 ноября 2019

Чтобы получить набор результатов, вам нужно только lag(), принимая во внимание как дату, так и сумму:

select t.*
from (select t.*,
             lag(amn) over (partition by dlrcode, rate order by dte) as prev_amn,
             lag(dte) over (partition by dlrcode, rate order by dte) as prev_dte
      from test t
     ) t
where prev_amn is null or
      prev_amn <> amn or
      prev_dte < dateadd(day, -1, dte);

Если вы хотите включить это в идентификатор группы, а затем суммировать группы- с информацией из нескольких строк - тогда мы добавим идентификатор группы в качестве кумулятивной суммы изменений группы и агрегируем:

select dlrcode, rate, amn, min(dte), max(dte),
       count(*)
from (select t.*,
             sum(case when prev_amn = amn and prev_dte >= dateadd(day, -1, dte)
                      then 0 else 1
                 end) over (partition by dlrcode, rate) as grp
      from (select t.*,
                   lag(amn) over (partition by dlrcode, rate order by dte) as prev_amn,
                   lag(dte) over (partition by dlrcode, rate order by dte) as prev_dte
            from test t
           ) t
     ) t
group by dlrcode, rate, amn, grp;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...