SQL Запрос к серверу для группировки и ранжирования записей с использованием повторяющихся значений - PullRequest
1 голос
/ 29 января 2020

Ниже приведены данные в моей исходной таблице:

Report_Date AccountNumber   eventtype
**1/1/2017  500000001   2
1/2/2017    500000001   2
1/3/2017    500000001   2**
**1/4/2017  500000001   1
1/5/2017    500000001   1**
**1/6/2017  500000001   2
1/8/2017    500000001   2
1/9/2017    500000001   2
1/10/2017   500000001   2
1/11/2017   500000001   2**
**1/12/2017 500000001   1
1/13/2017   500000001   1
1/15/2017   500000001   1
1/16/2017   500000001   1
1/17/2017   500000001   1**
**1/18/2017 500000001   2
1/19/2017   500000001   2
1/20/2017   500000001   2**

Мой sql вывод запроса сервера должен быть таким:

AccountNumber   eventtype   StartDt EndDt
500000001   2   1/1/2017    1/3/2017
500000001   1   1/4/2017    1/5/2017
500000001   2   1/6/2017    1/11/2017
500000001   1   1/12/2017   1/17/2017
500000001   2   1/18/2017   1/20/2017

Я много пробовал, используя все возможные комбинации с использованием RANK, ROW_NUMBER, DENSE_RANK et c. Но изо всех сил, чтобы получить желаемый результат. Любая помощь будет высоко оценена.

Я использую запрос:

Select a.*, 
 row_number() Over (partition by eventtype ORDER BY  aCCOUNTnUMBER,eventtype) as rank 
from
(
SELECT 
    [Report_Date],
        [AccountNumber],

          case when [DelqLevel] > 0 Then '1' 
  Else '2' End as eventtype


  FROM tab 
where 
[AccountNumber] = '500000001'
)a
Order by 2,1

Ответы [ 3 ]

0 голосов
/ 29 января 2020

Это проблема пробелов и островков. Одним из решений является различие номеров строк, которое успешно работает в SQL Server 2008:

select accountnumber, eventtype, min(report_date), max(report_date)
from (select t.*,
             row_number() over (partition by accountnumber order by report_date) as seqnum,
             row_number() over (partition by accountnumber, eventtype order by report_date) as seqnum_e
      from t
     ) t
group by accountnumber, eventtype, (seqnum - seqnum_e);

Почему это немного сложно объяснить. Но если вы посмотрите на результаты подзапроса, вы увидите, как разница в двух значениях номеров строк идентифицирует «смежные» записи с одинаковым типом события.

0 голосов
/ 30 января 2020

Я думаю, вы можете попробовать это:

SELECT
    AccountNumber,
    EventType,
    MIN(ReportDate) StartDt,
    MAX(ReportDate) EndDt

FROM (
    SELECT
        t.*,
        ISNULL(t2.ReportDate, CAST('9999-12-31 23:59:59.998' AS DATETIME)) GroupDate
    FROM tab t

    LEFT JOIN tab t2
        ON t2.AccountNumber = t.AccountNumber
            AND t2.ReportDate > t.ReportDate
            AND t2.EventType <> t.EventType

    WHERE
        t.AccountNumber = '500000001'
) t3

GROUP BY
    GroupDate, AccountNumber, EventType

Надеюсь, это поможет.

0 голосов
/ 29 января 2020

Это типичная проблема пробелов и островов, когда требуется оглянуться назад на раздел. Один из способов сделать это заключается в следующем:

DECLARE @T TABLE(ReportDate DATETIME, EventType INT, AccountNumber INT)
INSERT @T VALUES

    ('1/1/2017',2,2),
    ('1/2/2017',2,2),
    ('1/3/2017',2,2),
    ('1/4/2017',1,4),
    ('1/5/2017',1,5),
    ('1/6/2017',2,6),
    ('1/8/2017',2,7),
    ('1/11/2017',2,5)


;WITH Markers AS
(
    SELECT
        *,
        VirtualGroupID = SUM(IsNewGroup) OVER (ORDER BY ReportDate)
    FROM
    (        
        SELECT
            EventType, AccountNumber,
            ReportDate,
            IsNewGroup = CASE WHEN ISNULL(LAG(EventType) OVER (ORDER BY ReportDate),EventType)<>EventType THEN 1 ELSE 0 END
        FROM
            @T d
    )AS X
)

SELECT 
    EventType= MAX(EventType),
    ReportDate = MIN(ReportDate),
    MReportDate = MAX(ReportDate)
FROM 
    Markers
GROUP BY
    VirtualGroupID
...