Получить сумму записей за последние 6 месяцев (неполные месяцы) - PullRequest
0 голосов
/ 12 декабря 2018

Мои данные выглядят примерно так

ProductNumber | YearMonth | Number
1               201803      1
1               201804      3
1               201810      6
2               201807      -3
2               201809      5

Теперь я хочу добавить дополнительную запись "6MSum", которая представляет собой сумму за последние 6 месяцев на номер продукта (не последние 6 записей),Обратите внимание, что данные YearMonth не полны, для каждого ProductNumber есть промежутки между ними, поэтому я не могу просто использовать последние 6 записей для суммы.Окончательный результат должен выглядеть примерно так:

ProductNumber | YearMonth | Number | 6MSum
1               201803      1        1
1               201804      3        4
1               201810      6        9
2               201807      -3       -3
2               201809      5        2

Кроме того, я не хочу вставлять сумму в таблицу, а вместо этого использую ее в запросе:

SELECT [ProductNumber],[YearMonth],[Number],
6MSum = CONVERT(INT,SUM...)
FROM ...

Iнашел много решений, которые используют «сумму за период», но только для последних X записей, а не для фактического условного заявления «YearMonth за последние 6 месяцев».

Любая помощь будет принята с благодарностью!

Это база данных SQL

РЕДАКТИРОВАТЬ / Ответ

Похоже, что пробелы в месяцах должнызаполнить данными, после чего что-то вроде

sum(Number) OVER (PARTITION BY category 
                      ORDER BY year, week 
                          ROWS 6 PRECEDING) AS 6MSum

должно работать.

Ссылка на решение: https://dba.stackexchange.com/questions/181773/sum-of-previous-n-number-of-columns-based-on-some-category

Ответы [ 4 ]

0 голосов
/ 13 декабря 2018

Просто чтобы предоставить еще один вариант.Вы можете использовать DATEFROMPARTS для построения допустимых дат из значения YearMonth, а затем искать значения в диапазонах дат.

Тестируется здесь: https://rextester.com/APJJ99843

SELECT 
    ProductNumber , YearMonth , Number  
INTO #t
FROM ( values 
    (1,  201803 ,     1  ),
    (1,  201804 ,     3  ),
    (1,  201810 ,     6  ),
    (2,  201807 ,     -3 ),
    (2,  201809 ,     5  )
) s (ProductNumber , YearMonth , Number)

SELECT *
,[6MSum] = (SELECT SUM(number) FROM #t WHERE
    ProductNumber = t.ProductNumber 
    AND DATEFROMPARTS(LEFT(YearMonth,4),RIGHT(YearMonth,2),1) --Build a valid start of month date
    BETWEEN 
        DATEADD(MONTH,-6,DATEFROMPARTS(LEFT(t.YearMonth,4),RIGHT(t.YearMonth,2),1)) --Build a valid start of month date 6 months back
        AND DATEFROMPARTS(LEFT(t.YearMonth,4),RIGHT(t.YearMonth,2),1)) --Build a valid end of month date
FROM #t t

DROP TABLE #t
0 голосов
/ 12 декабря 2018

Таким образом, рабочий запрос (предоставленный моим коллегой) может выглядеть следующим образом

SELECT [YearMonth]
 ,[Number]
 ,[ProductNumber]
 , (Select Sum(Number) from [...] DPDS_1 where DPDS.ProductNumber = 
DPDS_1.ProductNumber and DPDS_1.YearMonth <= DPDS.YearMonth and DPDS_1.YearMonth >= 
convert (int, left (convert (varchar, dateadd(mm, -6, DPDS.YearMonth + '01'), 112), 
6)))FROM [...] DPDS
0 голосов
/ 12 декабря 2018

Используйте outer apply и конвертируйте yearmonth в дату, что-то вроде этого:

with t as (
      select t.*,
             convert(date, convert(varchar(255), yearmonth) + '01')) as ymd
      from yourtable t
     )
select t.*, t2.sum_6m
from t outer apply
     (select sum(t2.number) as sum_6m
      from t t2
      where t2.productnumber = t.productnumber and
            t2.ymd <= t.ymd and
            t2.ymd > dateadd(month, -6, ymd)
     ) t2;
0 голосов
/ 12 декабря 2018

Вы можете пойти по маршруту OUTER APPLY.Следующие результаты дают требуемые результаты:

-- prep data 
SELECT 
    ProductNumber , YearMonth , Number  
into #t
FROM ( values 
    (1,  201803 ,     1  ),
    (1,  201804 ,     3  ),
    (1,  201810 ,     6  ),
    (2,  201807 ,     -3 ),
    (2,  201809 ,     5  )
) s (ProductNumber , YearMonth , Number)

-- output
SELECT 
    ProductNumber 
    ,YearMonth 
    ,Number 
    ,[6MSum]
FROM #t t
outer apply ( 
    SELECT 
        sum(number) as [6MSum]
    FROM #t it
    where 
        it.ProductNumber = t.ProductNumber 
    and it.yearmonth <= t.yearmonth 
    and t.yearmonth - it.yearmonth between 0 and 6    
) tt


drop table #t
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...