在BigQuery中提取本月的工作日和工作日

时间:2016-06-29 15:08:48

标签: google-bigquery

我正在做两件事 - 我正在尝试一个。)只能在一个月内提取工作日,并且b。)该月的工作日是什么。

所以我知道工作日部分可以通过使用DAYOFWEEK功能完成并摆脱等于1或7的所有日子,但我对如何解决月份的营业日部分感到有点困惑。例如,今天将是本月的第21个工作日,但是另一个月的第21个工作日可能不是第29个,因此比较这种方式是没有意义的。这可能是一个周末。为了简化这一过程,我们不必担心一个典型工作日(即阵亡将士纪念日)的假期。

所以我的目标基本上是让你有一个输出 -

第1列:ID(我们可以说这是三个字符随机生成的字母数字ID)

第2栏:start_date

第3栏:星期几

第4栏:start_date月内的营业日

有人有什么建议吗?

2 个答案:

答案 0 :(得分:1)

  

在开始和结束日期之间提取营业日

在下面的示例中,开始日期为“2016-06-01”,结束日期为“2016-06-30”

SELECT 
  DATE(DATE_ADD(TIMESTAMP('2016-06-01'), pos - 1, "DAY")) AS business_day
FROM (
     SELECT ROW_NUMBER() OVER() AS pos, *
     FROM (FLATTEN((
     SELECT SPLIT(RPAD('', 1 + DATEDIFF(TIMESTAMP('2016-06-30'), TIMESTAMP('2016-06-01')), '.'),'') AS h
     FROM (SELECT NULL)),h
)))
HAVING DAYOFWEEK(business_day) NOT IN (1,7)
  

在开始和结束日期之间找到第N个工作日

在下面的示例中,开始日期为“2016-06-01”,结束日期为“2016-06-30”,N = 21

SELECT 
  business_day
FROM (
  SELECT
    business_day,
    ROW_NUMBER() OVER(ORDER BY business_day) AS number
  FROM (
    SELECT 
      DATE(DATE_ADD(TIMESTAMP('2016-06-01'), pos - 1, "DAY")) AS business_day
    FROM (
         SELECT ROW_NUMBER() OVER() AS pos, *
         FROM (FLATTEN((
         SELECT SPLIT(RPAD('', 1 + DATEDIFF(TIMESTAMP('2016-06-30'), TIMESTAMP('2016-06-01')), '.'),'') AS h
         FROM (SELECT NULL)),h
    )))
    HAVING DAYOFWEEK(business_day) NOT IN (1,7)
  )
)
WHERE number = 21

答案 1 :(得分:1)

尝试以下

SELECT
  start_date, 
  business_day, 
  DAYOFWEEK(business_day) AS day_of_week,
  ROW_NUMBER() OVER(PARTITION BY start_date ORDER BY business_day) AS business_day_number
FROM (
  SELECT 
    start_date, DATE(DATE_ADD(TIMESTAMP(start_date), pos - 1, "DAY")) AS business_day
  FROM (
    SELECT start_date, ROW_NUMBER() OVER() AS pos
    FROM (FLATTEN((
      SELECT start_date, SPLIT(RPAD('', 1 + DATEDIFF(TIMESTAMP(end_date), TIMESTAMP(start_date)), '.'),'') AS h
      FROM 
        (SELECT '2016-01-01' AS start_date, '2016-01-31' AS end_date),
        (SELECT '2016-03-01' AS start_date, '2016-03-31' AS end_date),
        (SELECT '2016-06-01' AS start_date, '2016-06-30' AS end_date)
    ), h
  )))
  HAVING DAYOFWEEK(business_day) NOT IN (1,7)

在我的脑海里 - 你改变了原来的问题 - 所以我认为提供单独的答案而不是添加到原来的答案是合适的

  

表名会去哪里?

假设YourTable如下所示:

start_date  end_date     
2016-01-01  2016-01-31   
2016-03-01  2016-03-31   
2016-06-01  2016-06-30

查询看起来像

SELECT
  start_date, 
  business_day, 
  DAYOFWEEK(business_day) AS day_of_week,
  ROW_NUMBER() OVER(PARTITION BY start_date ORDER BY business_day) AS business_day_number
FROM (
  SELECT 
    start_date, DATE(DATE_ADD(TIMESTAMP(start_date), pos - 1, "DAY")) AS business_day
  FROM (
    SELECT start_date, ROW_NUMBER() OVER() AS pos
    FROM (FLATTEN((
      SELECT start_date, SPLIT(RPAD('', 1 + DATEDIFF(TIMESTAMP(end_date), TIMESTAMP(start_date)), '.'),'') AS h
      FROM YourTable), h
  )))
  HAVING DAYOFWEEK(business_day) NOT IN (1,7)