Google bigquery 去年的星期几

Google bigquery 去年的星期几,google-bigquery,Google Bigquery,我试图在标准的SQL BigQuery中计算去年同一周的等效当天的日期 例如,如果当前日期2019-07-01是第27周的星期一。我想知道去年(2018年)第27周星期一的日期 当前周将是选择提取(从当前日期开始的isoweek()) 但我不知道如何用这个来计算日期 如果当前日期为2019-07-01,则预计产量为2018-07-02 这样做的原因是我想将当前的销售额与去年的同一周和同一天进行比较 任何建议都将不胜感激。诸如此类的建议会让您如愿以偿 with dates as (select *

我试图在标准的SQL BigQuery中计算去年同一周的等效当天的日期

例如,如果当前日期2019-07-01是第27周的星期一。我想知道去年(2018年)第27周星期一的日期

当前周将是
选择提取(从当前日期开始的isoweek())
但我不知道如何用这个来计算日期

如果当前日期为2019-07-01,则预计产量为2018-07-02

这样做的原因是我想将当前的销售额与去年的同一周和同一天进行比较


任何建议都将不胜感激。

诸如此类的建议会让您如愿以偿

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\u date()
参数来修改它以满足您的需要。

类似的内容应该可以让您继续

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()
参数根据需要修改它。

此查询不返回任何结果,这意味着
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

此查询不返回任何结果,这意味着
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

如果上一年没有等价物呢?有些年份的ISO周数不同。你说得对。这一直是个问题,但这是如何衡量的。如果上一年没有等价物呢?有些年份的ISO周数不同。你说得对。这一直是个问题,但这是如何衡量的。谢谢。这给了一些如何进行的想法!我将创建一个表并加入这个“日历”表。示例SQL返回2019-12-30的两个条目。一个用于2018-01-01周一,另一个用于2018-12-31周一(后者似乎是正确的,因为它是前12个月),谢谢。这给了一些如何进行的想法!我将创建一个表并加入这个“日历”表。示例SQL返回2019-12-30的两个条目。一个用于2018-01-01周一,一个用于2018-12-31周一(后者似乎是正确的,因为它是前12个月),谢谢!尽管我将使用其他解决方案,但这给了我未来使用的好主意。谢谢!尽管我将使用其他解决方案,但这给了我未来使用的好主意。