【问题标题】:Extracting Business Days and Business Day of Current Month in BigQuery在 BigQuery 中提取当月的工作日和工作日
【发布时间】:2016-06-29 15:08:47
【问题描述】:

我想做两件事 - 我正在尝试 a.) 仅提取一个月内的工作日和 b.) 它所在月份的工作日。

所以我知道工作日部分可以通过使用 DAYOFWEEK 函数并去掉等于 1 或 7 的所有天数来完成,但我对如何解决每月的工作日部分感到有些困惑。例如,今天是本月的第 21 个工作日,但另一个月的第 21 个工作日可能不是 29 日,所以这种比较没有意义。这可能是一个周末。为了简单起见,我们不必担心在典型工作日(即阵亡将士纪念日)的假期。

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

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

第 2 列:开始日期

第 3 列:星期几

第 4 列:start_date 月内的工作日

有人有什么建议吗?

【问题讨论】:

    标签: google-bigquery


    【解决方案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
    

    【讨论】:

    • 谢谢你,但只是一个澄清的问题......我的表名会去哪里?
    • 我的回答通过可靠的示例为您提供了一个想法,但如果您想要实际实施 - 您需要提供有关您的案例的更多信息 - 输入是什么,预期输出是什么。到目前为止,这不是您的问题的一部分。
    • 所以基本上有一个名为 start_date 的字段为您提供格式为 YYYY-MM-DD 的日期...我不太确定您需要什么?
    • 您的输入数据是什么(显示几行的示例)以及预期的输出 - 在您的问题中添加这些
    • 明白了。所以我的目标基本上是有一个输出给你 - 第 1 列:ID 第 2 列:start_date 第 3 列:星期几第 4 列:start_date 月内的工作日
    【解决方案2】:

    下面试试

    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)
    

    )

    【讨论】:

    • 谢谢!但同样,表名会去哪里?
    • 对不起,我认为这很明显。添加到答案
    猜你喜欢
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-26
    • 2016-06-06
    相关资源
    最近更新 更多