Найти максимальный непрерывный период для многократной регистрации на SQL сервере - PullRequest
1 голос
/ 27 апреля 2020

Я пытаюсь найти максимальное количество дней для каждого Cust_Nbr. Для каждого года у него может быть несколько с или без перерывов, в примере ниже Cust имеет 3 PolicNo, и для этого случая мне нужно найти, что max дней = 5 (как для PolicNo = 1) и max = 2 для других. Я пытался работать с некоторыми числами, закончил с таблицей, как показано ниже, но не уверен, как я могу go через все это для каждого на Cust_Nbr поймать любой перерыв. Цените ваши лиды. Я также вставил тестовые данные. Все еще есть ошибки в моем коде. enter image description here

Drop table if exists #T;

CREATE TABLE #t (Cust_Nbr int, PolicNo int, ENR_START Date, ENR_END  DATE, DD Date,  DayNum int, DayNum_Prev Int)
insert #t values
        (11111, 1, '11/27/2019', '12/1/2019', '11/27/2019', 331, 0),
        (11111, 1, '11/27/2019', '12/1/2019', '11/28/2019', 332, 331),
        (11111, 1, '11/27/2019', '12/1/2019', '11/29/2019', 333, 332),
        (11111, 1, '11/27/2019', '12/1/2019', '11/30/2019', 334, 333),
        (11111, 1, '11/27/2019', '12/1/2019', '12/1/2019', 335, 334),
        (11111, 22,'12/8/2019', '12/10/2019', '12/8/2019', 342, 335),
        (11111, 22, '12/8/2019', '12/10/2019', '12/9/2019', 343, 342),
        (11111, 22, '12/8/2019', '12/10/2019', '12/10/2019', 344, 343),
        (11111, 333, '12/26/2019', '12/29/2019', '12/26/2019', 360, 344),
        (11111, 333, '12/26/2019', '12/29/2019', '12/27/2019', 361, 360),
        (11111, 333, '12/26/2019', '12/29/2019', '12/28/2019', 362, 361),
        (11111, 333, '12/26/2019', '12/29/2019', '12/29/2019', 363, 362),
        (999999, 90, '12/8/2019', '12/9/2019', '12/8/2019', 342, 0),
        (999999, 90, '12/8/2019', '12/9/2019', '12/9/2019', 343, 342)

Select t.* , Days_Max = ( SELECT TOP 1 Cust_Nbr, COUNT(*) 
                          FROM #t t2 
                          WHERE  t2.Cust_Nbr = t.Cust_Nbr
                         )
            FROM #t t

Ответы [ 2 ]

1 голос
/ 27 апреля 2020

Глядя на пример, вы можете сделать это с помощью приведенного ниже запроса.

;WITH CTE1 AS
(
  SELECT Cust_Nbr,
       PolicNo,
       COUNT(DayNum_Prev) as max_days,
       ROW_NUMBER() OVER (PARTITION BY Cust_Nbr ORDER BY COUNT(DayNum_Prev) DESC) RN
  FROM #t
  GROUP BY Cust_Nbr,PolicNo
)
SELECT Cust_Nbr ,PolicNo,max_days FROM CTE1 WHERE RN=1

Или используя свои логики c, как показано ниже

;WITH CTE2 AS
(
    SELECT *,ROW_NUMBER() OVER (ORDER BY Cust_Nbr,PolicNo) Rnk , 
           CASE WHEN DayNum_Prev=DayNum-1 THEN 0 ELSE 1 END cols 
    FROM #t
)
,CTE3 AS
(
   SELECT *,SUM(cols) OVER(ORDER BY Rnk) Grouper FROM CTE2
)
,CTE4 AS
(
    SELECT Cust_Nbr,PolicNo,count(*) MAX_DAYS,
           ROW_NUMBER() OVER (PARTITION BY Cust_Nbr ORDER BY COUNT(*) DESC) RN 
    FROM CTE3
    GROUP BY Cust_Nbr,PolicNo,grouper
)
SELECT CUST_NBR,POLICNO,MAX_DAYS FROM CTE4 WHERE RN =1

Проверьте демо здесь

1 голос
/ 27 апреля 2020

Ниже решение находится в PostgreSQL, но вы можете применить аналогичные логи c в t sql. вот это демо .

select
    cust_nbr,
    policNo,
    total
from    
(
  select
        cust_nbr,
        policNo,
        count(rnk)  as total,
        dense_rank() over (partition by cust_nbr order by count(rnk) desc) as nrnk
    from
    (
      select
            cust_nbr,
            policNo,
            (dd - '2000-01-01'::date 
             - row_number() over (partition by cust_nbr, policNo order by dd)) as rnk
        from myTable
    ) val
    group by
        cust_nbr,
        policNo,
        rnk
) res
where nrnk = 1

Выход:

*-----------------------*
|cust_nbr policno total |
*-----------------------*
|11111       1      5   |
|999999      99     2   |
*-----------------------*
...