Вычисление суммы количества для N строк с номером недели, которые находятся в диапазоне недель в текущей строке - PullRequest
0 голосов
/ 05 марта 2020

У меня есть таблица, в которой есть столбцы категория A , категория B , год , месяц , неделя и количество , соответствующее заданному значению c.

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

Я попробовал приведенный ниже код

запрос 1

select
    categoryA
    , categoryB
    , year
    , month
    , week
    , SUM(quantity) OVER 
            PARTITION BY(categoryA, categoryB 
            ORDER BY categoryA, categoryB, year, month, week rows BETWEEN 12 PRECEDING AND 1 PRECEDING)
FROM TABLE1

Но проблема в том, что на неделе могут быть пробелы, например Год 2020 может не иметь строки для недели 20, в этом случае количество для этой строки должно рассматриваться как 0.

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

query 2

SELECT year,week, month, categoryA, categoryB,
                        CASE WHEN week> 12 THEN week- 12
                             WHEN week= 1 THEN 0
                             ELSE 1 END AS startWeek1,
                        CASE WHEN week<> 1 THEN week- 1
                             WHEN week= 1 THEN 0 END AS endWeek1,

                        CASE WHEN week<> 1 THEN year
                             ELSE 0 END AS startYear, 
                        CASE WHEN week> 12 THEN 0
                             ELSE year- 1 END AS EndYear,

                        CASE WHEN week> 12 THEN 0
                             ELSE datepart(week, DATEFROMPARTS(year -1, 12, 31)) - (12 - week) END AS startWeek2,
                        CASE WHEN week > 12 THEN 0
                             ELSE datepart(week, DATEFROMPARTS(year-1, 12, 31)) END AS endWeek2

Но теперь я должен как-то сравнить, подпадают ли последние 12 строк под диапазон недель и лет, указанный в текущей строке в моем запросе 1

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

В моей таблице есть данные примерно такие:

year   month  week  categoryA  categoryB  quantity
2020   1      1     steel      white      2
2020   1      2     steel      white      4
2020   2      5     steel      white      5
2020   2      6     steel      white      1
2020   10     40    steel      white      1
2020   10     41    steel      white      10

Ожидаемый результат:

year   month  week  categoryA  categoryB  quantity  lastTwelveWeeksQuantity
2020   1      1     steel      white      2          0
2020   1      2     steel      white      4          2
2020   2      5     steel      white      5          6
2020   2      6     steel      white      1          11 
2020   10     40    steel      white      1          0
2020   10     41    steel      white      10         1

РЕДАКТИРОВАТЬ Другой вариант использования с неделями, охватывающими годы, и должен быть сгруппирован по категориям A и категории B

 year   month  week  categoryA  categoryB  quantity
    2019   12     43    steel      white      2
    2020   1      1     steel      white      2
    2020   1      2     steel      white      4
    2020   2      5     steel      white      5
    2020   2      6     steel      white      1
    2020   10     40    steel      white      1
    2020   10     41    steel      white      10

Ожидаемый результат:

year   month  week  categoryA  categoryB  quantity  lastTwelveWeeksQuantity
2019   12     43    steel      white      2         0
2019   12     53    steel      blue       2         0
2020   1      1     steel      white      2         2 
2020   1      2     steel      white      4         4(considering quantity from 2019 as it falls in range for last 12 weeks i,e week 1 in 2020 and week 53 to 43 in 2019) 
2020   2      5     steel      white      5         6
2020   2      6     steel      white      1         11
2020   10     40    steel      white      1         0
2020   10     41    steel      white      10        1

Ответы [ 2 ]

0 голосов
/ 06 марта 2020

Был в состоянии прийти к этому ответу, улучшив решение @MrKnino, чтобы охватить сценарий с неделями, охватывающими годы. Но производительность очень плохая, у меня 800000 строк, и, вероятно, на выполнение уходит более часа, поскольку подзапрос должен выполняться для каждой строки

    create table #exampleStack(anio numeric,mes numeric,semana numeric,categoryA varchar(50),categoryB varchar(50),quantity numeric)

INSERT INTO #exampleStack VALUES('2019','12 ','43 ','steel','white','2')
INSERT INTO #exampleStack VALUES('2019','12 ','53 ','steel','blue','2')
INSERT INTO #exampleStack VALUES('2020','1 ','1 ','steel','white','2')
INSERT INTO #exampleStack VALUES('2020','1 ','2 ','steel','white','4')
INSERT INTO #exampleStack VALUES('2020','2 ','5 ','steel','white','5')
INSERT INTO #exampleStack VALUES('2020','2 ','6 ','steel','white','1')
INSERT INTO #exampleStack VALUES('2020','10','40','steel','white','1')
INSERT INTO #exampleStack VALUES('2020','10','41','steel','white','10')

SELECT 
A.anio,A.mes,A.semana,A.categoryA,A.categoryB,A.quantity
,(SELECT ISNULL(SUM(quantity),0) 
 FROM #exampleStack 
WHERE ( categoryB = A.categoryB AND categoryA = A.categoryA AND anio = A.anio and semana >= A.semana-12 and semana < A.semana) OR (anio = A.anio - 1 and 
semana >= datepart(week, DATEFROMPARTS(anio -1, 12, 31)) - (12 - A.semana) and semana <= datepart(week, DATEFROMPARTS(anio -1, 12, 31))) )
FROM #exampleStack AS A
0 голосов
/ 06 марта 2020

Здесь у вас есть подзапрос.

create table #exampleStack(anio numeric,mes numeric,semana numeric,categoryA varchar(50),categoryB varchar(50),quantity numeric)

INSERT INTO #exampleStack VALUES('2020','1 ','1 ','steel','white','2')
INSERT INTO #exampleStack VALUES('2020','1 ','2 ','steel','white','4')
INSERT INTO #exampleStack VALUES('2020','2 ','5 ','steel','white','5')
INSERT INTO #exampleStack VALUES('2020','2 ','6 ','steel','white','1')
INSERT INTO #exampleStack VALUES('2020','10','40','steel','white','1')
INSERT INTO #exampleStack VALUES('2020','10','41','steel','white','10')

SELECT 
A.anio,A.mes,A.semana,A.categoryA,A.categoryB,A.quantity
,(SELECT ISNULL(SUM(quantity),0) FROM #exampleStack WHERE anio<=A.anio and mes<=A.mes  and semana>=A.semana-13 and semana<A.semana)
FROM #exampleStack AS A
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...