Как рассчитать данные о продажах за предыдущий год в SQL - PullRequest
0 голосов
/ 11 апреля 2019

Я пытаюсь построить таблицу, обобщающую данные о продажах за неделю.В нем я пытаюсь, чтобы в одном из соседних столбцов отображались цифры продаж за ту же финансовую неделю в предыдущем году (в которой, согласно финансовому календарю моей организации, в прошлом году была 53-я неделя).Мне также нужно сравнить (Comp Units / Comp Sales) с периодом 52 недели назад, который является совершенно другой фискальной неделей (думаю, неделя 9 из 2019 по сравнению с неделей 10 2018).

Я пытался использоватьи объединения, и полные внешние объединения, но, учитывая мои данные, они неэффективны (поскольку это еженедельные данные, объединения оказались неэффективными, так как мне нужно было исключить информацию о дате из исходного запроса, а затем обновить столбцыв моей таблице, чтобы отразить неделю, для которой данные. Это, очевидно, изобилует возможностью для ошибки, но также требует много времени, чтобы сделать 105 раз), или просто не работает (попытка полного внешнего соединения возвращала неправильные ответы для всехколонны).Я также пытался использовать CTE, и это тоже не работает для меня.В настоящее время я пытаюсь использовать оператор CASE, но он также возвращает нулевое значение.Я не совсем уверен, куда идти дальше

#STANDARDSQL
SELECT 
 DTL.SKU_NBR                                                      AS SKU_NBR
, SLS.STR_NBR                                                     AS STR_NBR
, CONCAT(TRIM(CAST(SKU_HIER.SKU_NBR AS STRING)), ' ', '-', ' ', TRIM(SKU_HIER.SKU_DESC))                                          AS SKU
, CONCAT(TRIM(CAST(SKU_HIER.EXT_SUB_CLASS_NBR AS STRING)), ' ', '-', ' ', TRIM(SKU_HIER.SUB_CLASS_DESC))                                    AS SUB_CLASS
, CONCAT(TRIM(CAST(SKU_HIER.EXT_SUB_SC_NBR AS STRING)), ' ', '-', ' ', TRIM(SKU_HIER.SUB_SC_DESC))                                 AS SUB_SUB_CLASS
, LOCATION.MKT_NM                                           AS MARKET_NAME
, LOCATION.RGN_NM                                           AS REGION_NAME
, LOCATION.DIV_NM                                           AS DIVISION_NAME
, LOCATION.DIV_NBR                                          AS DIVISION_NUMBER
, LOCATION.RGN_NBR                                          AS REGION_NUMBER
, LOCATION.MKT_NBR                                          AS MARKET_NUMBER
, COMP.STR_COMP_IND                                         AS COMP_IND
, COMP.PY_STR_COMP_IND                                      AS PRIOR_COMP_IND
, CALENDAR.FSCL_WK_DESC                                     AS FISCAL_WEEK
, CALENDAR.FSCL_PRD_DESC                                    AS FISCAL_PERIOD
, CALENDAR.FSCL_WK_END_DT                                   AS END_DATE
, CALENDAR.FSCL_WK_BGN_DT                                   AS BEGIN_DATE
, CALENDAR.FSCL_YR                                          AS FISCAL_YEAR_NBR
, CALENDAR.FSCL_WK_NBR                                      AS WEEK_NUMBER
, CALENDAR.FSCL_YR_WK_KEY_VAL                               AS FISCAL_KEY
, CALENDAR.LY_FYR_WK_KEY_VAL                                AS LY_FISCAL_KEY
, SUM(COALESCE(DTL.UNT_SLS,0))                              AS UNITS
, SUM(COALESCE(DTL.EXT_RETL_AMT,0) + COALESCE(DTL.TOT_GDISC_DTL_AMT,0))                                                                                        
                                                            AS SALES
, SUM(CASE
            WHEN 1=1 THEN (COALESCE(DTL.EXT_RETL_AMT,0) + COALESCE(DTL.TOT_GDISC_DTL_AMT,0)) * COMP.STR_COMP_IND
            ELSE 0 END)                                     AS COMP_SALES
, SUM(CASE
            WHEN 1=1 THEN (COALESCE(DTL.UNT_SLS,0)) * COMP.STR_COMP_IND
            ELSE 0 END)                                     AS COMP_UNITS
, SUM(CASE
            WHEN 1=1 AND SLS.SLS_DT = DATE_SUB(SLS.SLS_DT, INTERVAL 364 DAY) 
            THEN (COALESCE(DTL.EXT_RETL_AMT,0) + 
            COALESCE(DTL.TOT_GDISC_DTL_AMT,0)) * COMP.PY_STR_COMP_IND
            ELSE NULL END)                                                                                                                                                 
                                                            AS LY_COMP_SALES
, SUM(CASE
            WHEN 1=1 AND SLS.SLS_DT = DATE_SUB(SLS.SLS_DT, INTERVAL 364 DAY)  
            THEN (COALESCE(DTL.UNT_SLS,0)) * COMP.PY_STR_COMP_IND
            ELSE NULL END)                                                                                                                                                 
                                                            AS LY_COMP_UNITS
, SUM(CASE 
            WHEN SLS.SLS_DT = DATE_SUB(SLS.SLS_DT, INTERVAL 371 DAY) 
            THEN (COALESCE(DTL.EXT_RETL_AMT,0) + 
            COALESCE(DTL.TOT_GDISC_DTL_AMT,0)) 
            ELSE NULL END)                                                                                                               
                                                            AS LY_SALES
, SUM(CASE 
            WHEN SLS.SLS_DT = DATE_SUB(SLS.SLS_DT, INTERVAL 371 DAY) 
            THEN (COALESCE(DTL.UNT_SLS,0)) 
            ELSE NULL END)                                                                                                               
                                                            AS LY_UNITS


FROM `pr-edw-views.SLS.POS_SLS_TRANS_DTL`                   AS SLS

INNER JOIN 
  UNNEST (SLS.DTL)                                          AS DTL 


JOIN `pr-edw-views.SHARED.MVNDR_HIER`                       AS MVNDR  
  ON DTL.DERIV_MVNDR.MVNDR_NBR = MVNDR.MVNDR_NBR

JOIN `pr-edw-views.SHARED.SKU_HIER_FD`                      AS SKU_HIER
  ON SKU_HIER.SKU_NBR = DTL.SKU_NBR
  AND SKU_HIER.SKU_CRT_DT = DTL.SKU_CRT_DT 

JOIN `pr-edw-views.SHARED.LOC_HIER_FD`                      AS LOCATION
  ON LOCATION.LOC_NBR = SLS.STR_NBR

JOIN `pr-edw-views.SHARED.CAL_PRD_HIER_FD`                  AS CALENDAR
  ON CALENDAR.CAL_DT = SLS_DT

JOIN `pr-edw-views.SLS.STR_COMP_DAY`                        AS COMP
  ON COMP.CAL_DT = CALENDAR.CAL_DT
  AND COMP.STR_NBR = SLS.STR_NBR


WHERE CALENDAR.FSCL_WK_END_DT BETWEEN '2018-01-29' AND '2019-04-07'
AND SLS.SLS_DT BETWEEN '2018-01-29' AND '2019-04-07'
AND POS_TRANS_TYP_CD in ('S', 'R')
AND SKU_HIER.EXT_CLASS_NBR = '025-004'
AND MVNDR.MVNDR_NBR IN (74798, 60002238, 73059, 206820, 76009, 40263, 12879, 76722, 10830, 206823, 87752, 60052261, 70401, 51415, 51414)
AND SKU_HIER.LATEST_SKU_CRT_DT_FLG = TRUE


GROUP BY
 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20

В настоящее время я получаю нулевые значения в моих столбцах LY_SALES, LY_UNITS, LY_COMP_SALES и LY_COMP_UNITS, хотя знаю, чтобыли места с продажами этих предметов за тот же период предыдущего года.То, к чему я пытаюсь добраться - это отображение значений предыдущего года вместе со значениями текущего года.Любая помощь будет принята с благодарностью!

Спасибо!

Ответы [ 2 ]

0 голосов
/ 11 апреля 2019

Две вещи: 1) WHEN 1=1 можно выразить просто как WHEN TRUE, таким образом легче перемещать операторы без прерывания цепочки И / ИЛИ

2), чтобы получить прошлогодние продажи. Вы можете либо опустить год в окончательном запросе и ограничить вывод предложением where, либо создать меньшую таблицу, в которой продажи в этом году будут продаваться в прошлом году за неделю.

По моему скромному мнению, продажи в прошлом году для Weeknum - лучший вариант, так как вы можете использовать его в другом месте. Но это очень похоже на то, что вы написали

Это будет выглядеть примерно так:

SELECT CALENDAR.FSCL_WK_DESC as week_num,
sum(case when year = year(current_date()) then (COALESCE(DTL.UNT_SLS,0)) * COMP.STR_COMP_IND else 0 end) as this_year
sum(case when year = year(current_date())-1 then (COALESCE(DTL.UNT_SLS,0)) * COMP.STR_COMP_IND else 0 end) as last_year 

А затем вы присоединяетесь к исходной таблице, используя week_num

Надеюсь, вы найдете это полезным

Ура!

0 голосов
/ 11 апреля 2019

Такое условие никогда не может быть выполнено: SLS.SLS_DT = DATE_SUB (SLS.SLS_DT, INTERVAL 371 DAY).Просто потому, что SLS_DT не равен SLS_DT-371.

Вы можете предварительно агрегировать таблицу в CTE (добавляя SLS_DT в группу по столбцам), а затем заменить CASE соединением с предварительно агрегированнымТаблица.Нацельтесь на что-то вроде этого: и это станет чем-то вроде (обратите внимание - в данном случае нет СУММЫ):

CASE WHEN AGGSLS.SLS_DT = DATE_SUB(SLS.SLS_DT, INTERVAL 371 DAY) 
THEN (COALESCE(AGGSLS.SUM_EXT_RETL_AMT,0) + 
COALESCE(AGGSLS.SUM_TOT_GDISC_DTL_AMT,0)) 
ELSE NULL END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...