День недели в прошлом году - PullRequest
0 голосов
/ 02 июля 2019

Я пытаюсь вычислить дату эквивалентного текущего дня в прошлом году на той же неделе в стандартном SQL BigQuery.

Например, если текущая дата 2019-07-01 - понедельник недели 27. Я хочу знать дату понедельника недели 27 в прошлом году (2018).

Текущая неделя будет select extract(isoweek from current_date()) но я не знаю, как использовать это для вычисления даты.

Ожидаемый результат - 2018-07-02, если текущая дата - 2019-07-01

Причина в том, что я хочу сравнить текущие продажи с той же неделей и днем ​​недели, что и в прошлом году.

Любые предложения приветствуются.

Ответы [ 2 ]

1 голос
/ 02 июля 2019

Этот запрос не возвращает результатов, подразумевая, что SHIFT работает. Функция возвращает NULL, если год не имеет того же количества недель, что и его предшественник.

CREATE TEMP FUNCTION P_YEAR(y INT64) AS (
  MOD(CAST(y + FLOOR(y / 4.0) - FLOOR(y / 100.0) + FLOOR(y / 400.0) AS INT64), 7)
);

CREATE TEMP FUNCTION WEEKS_YEAR(y INT64) AS (
  52 + IF(P_YEAR(y) = 4 OR P_YEAR(y - 1) = 3, 1, 0)
);

CREATE TEMP FUNCTION SHIFT(d DATE) RETURNS DATE AS (
  CASE
    WHEN WEEKS_YEAR(EXTRACT(ISOYEAR FROM d)) != WEEKS_YEAR(EXTRACT(ISOYEAR FROM d) - 1)
      THEN null
    WHEN WEEKS_YEAR(EXTRACT(ISOYEAR FROM d)) = 52
      THEN DATE_SUB(d, INTERVAL 52 WEEK)
    ELSE d
  END
);

WITH dates AS (
SELECT d
FROM UNNEST(GENERATE_DATE_ARRAY('2000-12-31', '2020-12-31', INTERVAL 1 DAY)) AS d
)
SELECT
 d,
 EXTRACT(ISOWEEK FROM d) AS orig_iso_week,
 EXTRACT(ISOWEEK FROM SHIFT(d)) AS new_iso_week,
 SHIFT(d) AS new_d
FROM dates
WHERE EXTRACT(ISOWEEK FROM d) != EXTRACT(ISOWEEK FROM SHIFT(d))
  AND SHIFT(d) IS NOT NULL
1 голос
/ 02 июля 2019

Что-то вроде этого должно заставить вас ...

with dates as (select * from unnest(generate_date_array('2018-01-01','2019-12-31', interval 1 day)) as cal_date),
       cal as (select cal_date, cast(format_date('%Y', cal_date) as int64) as year, cast(format_date('%V', cal_date) as int64) as week_num, format_date('%A', cal_date) as weekday_name from dates)
select c1.cal_date, c1.week_num, c1.weekday_name, c2.cal_date as previous_year_same_weekday
from cal c1
inner join cal c2 
  on c1.year = c2.year+1 and c1.week_num = c2.week_num and c1.weekday_name = c2.weekday_name

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

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