Я пытаюсь сравнить между неделей и следующей за три года в SQL - PullRequest
0 голосов
/ 06 марта 2019

Я пытаюсь вычислить разницу посетителей магазина между неделей и следующей, и я использую запрос, который вычисляет эту разницу только между неделями того же года, а НЕ ПОСЛЕДНЕЙ НЕДЕЛЕ ГОДА И ПЕРВАЯ НЕДЕЛЯ СЛЕДУЮЩЕГО ГОДА (53 неделя в 2016 году и 1 неделя в 2017 году)!

Вот как выглядит мой стол


| Дата | ГОД | НЕДЕЛЯ | StoreName | Number_Of_Vistors |


Кто-нибудь, как я могу сделать запрос, который выполняется в течение всех недель в течение трех лет?

Вот как я написал свой запрос:

SELECT
    (base.Store_Visitors-lw.Store_Visitors)/lw.Store_Visitors AS VARIANCE
FROM
  `myproject` base
JOIN (
  SELECT
    *, extract(WEEK FROM (DATE_ADD(DATE(TIMESTAMP(date)) , INTERVAL 1 Week))) AS n_week

  FROM
    `myproject` ) lw
ON
  base.WEEK = (lw.n_week-1)
  AND base.YEAR = lw.YEAR
  AND base.DAYOFWEEK = lw.DAYOFWEEK

  AND base.Store_Name = lw.Store_Name

Ответы [ 2 ]

1 голос
/ 08 марта 2019

Ниже для стандартного SQL BigQuery и использования аналитических функций вместо самостоятельного объединения

#standardSQL
WITH temp AS (
  SELECT 
    EXTRACT(YEAR FROM t.date) year, 
    EXTRACT(WEEK FROM t.date) week, 
    Store_Name, 
    Number_Of_Vistors
  FROM `project.dataset.table` t
)
SELECT Store_Name, year, week, 
  (Number_Of_Vistors - ANY_VALUE(Number_Of_Vistors) 
    OVER(PARTITION BY Store_Name, year ORDER BY week RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING)
  ) / Number_Of_Vistors AS variance
FROM temp t   

Вы можете проверить, поиграть с выше, используя фиктивные данные, как в примере ниже

#standardSQL
WITH `project.dataset.table` AS (
  SELECT DATE '2018-12-02' `date`, 'abc' Store_Name, 11 Number_Of_Vistors UNION ALL
  SELECT '2018-12-09', 'abc', 22 UNION ALL
  SELECT '2018-12-16', 'abc', 33 UNION ALL
  SELECT '2018-12-23', 'abc', 44 UNION ALL
  SELECT '2018-12-30', 'abc', 55 UNION ALL
  SELECT '2019-01-06', 'abc', 66 UNION ALL
  SELECT '2019-01-13', 'abc', 77 UNION ALL
  SELECT '2019-01-20', 'abc', 88 
), temp AS (
  SELECT 
    EXTRACT(YEAR FROM t.date) year, 
    EXTRACT(WEEK FROM t.date) week, 
    Store_Name, 
    Number_Of_Vistors
  FROM `project.dataset.table` t
)
SELECT Store_Name, year, week, 
  (Number_Of_Vistors - ANY_VALUE(Number_Of_Vistors) 
    OVER(PARTITION BY Store_Name, year ORDER BY week RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING)
  ) / Number_Of_Vistors AS variance
FROM temp t
ORDER BY Store_Name, year, week   

с результатом

Row Store_Name  year    week    variance     
1   abc         2018    48      null     
2   abc         2018    49      0.5  
3   abc         2018    50      0.3333333333333333   
4   abc         2018    51      0.25     
5   abc         2018    52      0.2  
6   abc         2019    1       null     
7   abc         2019    2       0.14285714285714285  
8   abc         2019    3       0.125     

Примечание: поскольку из вашего вопроса не ясно, как именно представлены ваши данные - я предполагаю, что у вас есть по одной строке в неделю в год на магазин

Вы должны быть в состоянии отрегулировать выше, по мере необходимости, к вашим фактическим типам данных / сценарию использования

1 голос
/ 06 марта 2019

Вам нужно указать номер ваших данных по неделям и годам и присоединиться к тому или иному неповторяющемуся значению ваших данных.

SELECT
    (base.Store_Visitors-lw.Store_Visitors)/lw.Store_Visitors AS VARIANCE,
    ROW_NUMBER() OVER( PARTITION BY Store_Name ORDER BY YEAR, WEEK) AS WeekOrder

FROM
  `BaseData` base
JOIN (
  SELECT
    *, extract(WEEK FROM (DATE_ADD(DATE(TIMESTAMP(date)) , INTERVAL 1 Week))) AS n_week,
   ROW_NUMBER() OVER( PARTITION BY Store_Name ORDER BY YEAR, WEEK) AS WeekOrder


  FROM
    `BaseData` ) lw
ON
  base.WeekOrder= lw.WeekOrder-1
  AND base.DAYOFWEEK = lw.DAYOFWEEK

  AND base.Store_Name = lw.Store_Name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...