Как получить промежуточные итоги за каждый квартал и вместо дубликата иметь значение 0. Использование SQL Server 2012 - PullRequest
0 голосов
/ 09 января 2019

Мне нужно рассчитать текущую премию за каждый квартал. Но мои данные разбиты по дате.

Так что мне нужно отображаемое значение первой строки на основе года и квартала, но если следующие строки имеют одинаковые Year и Quarter, тогда значение должно быть 0.

Вот как это выглядит сейчас:

enter image description here

Но мне нужно вот так:

enter image description here

Запрос с фиктивными данными:

declare @TempTable1 table (ID int, Date date, PolicyNumber varchar(100), Premium money)

insert into @TempTable1 
values (1, '2018-01-01', 'Policy1', 100),
       (2, '2018-02-08', 'Policy2', 200),
       (3, '2018-04-15', 'Policy3', 300),
       (4, '2018-05-31', 'Policy4', 150),
       (5, '2018-07-10', 'Policy5', 250),
       (6, '2018-11-23', 'Policy6', 350),
       (7, '2018-12-05', 'Policy7', 330),
       (8, '2019-01-09', 'Policy8', 140),
       (9, '2019-06-18', 'Policy9', 225),
       (10, '2019-06-28', 'Policy10', 145)

SELECT  
    ID, 
    Date, 
    PolicyNumber,    
    YEAR(date) AS Year, 
    DATEPART(qq, date) AS Quarter,
    Premium,
    SUM(premium) OVER (ORDER BY YEAR(date), DATEPART(qq, date)) AS RunningTotal
FROM
    @TempTable1

Возможно ли достичь этого в том же SELECT утверждении?

Спасибо

Ответы [ 2 ]

0 голосов
/ 09 января 2019

попробуйте это. Он создает row_number для каждого года и квартала и допускает только вычисленное значение для row = 1

SELECT ID,
        Date,
        policynumber, 
        dq2.year,
        dq2.Quarter,
        premium,
        case when rn=1 then runningtotal else 0 end 'runningtotal' 
from
    (
        select *,row_number() OVER (partition by year,quarter order by policynumber) as RN FROM
        (
        select  ID, 
                Date, 
                PolicyNumber,    
                Year(date) as 'Year', 
                DATEPART(qq,date) as [Quarter],
                Premium,
                sum(premium) over (order by Year(date),DATEPART(qq,date)) as RunningTotal

        from @TempTable1
        ) DQ
    ) DQ2
0 голосов
/ 09 января 2019

Все, что вам нужно сделать, это добавить проверку, чтобы увидеть, меняется ли Year / Quarter или нет через оконную функцию lag().

select  ID, 
        Date, 
        PolicyNumber,    
        Year(date) as Year, 
        DATEPART(qq,date) as Quarter,
        Premium,
        case when lag(DATEPART(qq,date), 1, null) over (order by Year(date),DATEPART(qq,date)) - DATEPART(qq,date) = 0 then 0 else
        sum(premium) over (order by Year(date),DATEPART(qq,date)) end as RunningTotal
from @TempTable1

Я бы предложил обернуть начальные вычисляемые столбцы в подзапрос, чтобы сократить количество задействованных datepart() calcs, но любое решение будет работать.

Опция подзапроса:

select a.ID
, a.Date
, a.PolicyNumber
, a.Year
, a.Quarter
, a.Premium
, case when lag(a.Quarter, 1, null) over (order by a.Year,a.Quarter) - a.Quarter = 0 then 0 else
            sum(a.premium) over (order by a.Year,a.Quarter) end as RunningTotal
from (
    select  ID, 
            Date, 
            PolicyNumber,    
            Year(date) as Year, 
            DATEPART(qq,date) as Quarter,
            Premium
    from @TempTable1
    ) as a
...