【问题标题】:Count of each day of the week between May 01, 2020 and April 30, 2021 in SQL(BigQuery)SQL(BigQuery) 中 2020 年 5 月 1 日至 2021 年 4 月 30 日之间一周中每一天的计数
【发布时间】:2021-09-01 22:36:33
【问题描述】:

我需要在 SQL(BigQuery) 中计算 2020 年 5 月 1 日至 2021 年 4 月 30 日期间一周中每一天的总出现次数(# of Sundays、# of Mondays 等)。

我有以下相关领域可以使用:

Field Type
started_at_cst DATETIME
ended_at_cst DATETIME
Day_of_Week STRING

期间的开始日期将是从 started_at_cst 开始的最早日期,结束日期将是从ended_at_cst 开始的最晚日期。

【问题讨论】:

  • 您希望结果是什么样的?数据是否以多行形式出现?

标签: sql google-bigquery


【解决方案1】:

首先,您应该创建您要创建报告的期间的每日记录。 为此,您可以创建一个表作为“日历表”。

CREATE TABLE dbo.CalendarTable
    (
    Date datetime NOT NULL,
    DayWeekNumber nvarchar(50) NULL
    )  ON [PRIMARY]
GO
ALTER TABLE dbo.CalendarTable ADD CONSTRAINT
    PK_CalendarTable PRIMARY KEY CLUSTERED 
    (
    Date
    ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
Go

之后你应该像这样填写日历表:


Truncate Table CalendarTable
Declare @FromDate as datetime , @ToDate as datetime, @counter as int , @DateRecord as int,
@Date as Datetime

Set @FromDate = '2020-03-21'
Set @ToDate = '2021-03-21'
Set @Counter = 1

Set @DateRecord = dateDiff(D,@FromDate, @ToDate)

While (@Counter <=@DateRecord)
BEGIN
Insert Into CalendarTable (Date,DayWeekNumber)
    Select DateAdd(d,@Counter,@FromDate),DATEPART(dw,DateAdd(d,@Counter,@FromDate))
Set @Counter += 1

END

最后将它与您的出现表连接起来

Select Date,(Select Count(*) From occurrencesTable Where started_at_cst>= CalendarTable.Date
and ended_at_cst<= CalendarTable.Date ) as NumberOfOccurence from CalendarTable

【讨论】:

    【解决方案2】:

    借助GENERATE_ARRAY 功能,您可以得到您想要的:

    WITH dow_generated AS (
        # Step 2. Extract the day of the week for each generated date
        SELECT
            FORMAT_DATE("%A",dates) AS day_of_week
        FROM (
                # Step 1. Generate an array of dates from minimum of started_at_cst to maximumn of ended_at_cst
                SELECT 
                    GENERATE_DATE_ARRAY(MIN(started_at_cst), MAX(ended_at_cst)) as dates
                FROM `your_table`) dates_generated, unnest(dates_generated.dates) dates)
    
    # Step 3. Count the different days of the week
    SELECT day_of_week, COUNT(day_of_week) AS day_count
    FROM dow_generated
    GROUP BY day_of_week
    

    你应该得到一个像这样的表:

    【讨论】:

      【解决方案3】:

      大概,您希望得到您指定格式的结果。如果是这样,这应该做你想要的:

      WITH t AS (
             select datetime('2020-05-01') as started_at_cst, datetime('2021-05-30') as ended_at_cst
      )
      SELECT FORMAT_DATE('%A', dte) AS day_of_week, COUNT(*) AS day_count
      FROM (SELECT MIN(started_at_cst) as min_started_at_cst, MAX(ended_at_cst) as max_ended_at_cst
            FROM t
           ) t CROSS JOIN
           UNNEST(GENERATE_DATE_ARRAY(DATE(min_started_at_cst), DATE(max_ended_at_cst), INTERVAL 1 day)) dte
      GROUP BY day_of_week
      ORDER BY MIN(dte)
      

      【讨论】:

        【解决方案4】:

        考虑下面

        select format_date('%A', day) day_of_the_week, count(1) days_count 
        from `project.dataset.table`,
        unnest(generate_date_array(date(started_at_cst), date(ended_at_cst))) day
        where day between '2020-05-01' and '2021-04-30'
        group by day_of_the_week    
        

        如果您希望输出按工作日排序 - 请在下方添加 order by

        order by case day_of_the_week
          when 'Monday' then 1
          when 'Tuesday' then 2
          when 'Wednesday' then 3
          when 'Thursday' then 4
          when 'Friday' then 5
          when 'Saturday' then 6
          when 'Sunday' then 7
        end     
        

        最后 - 如果上面的顺序对你来说太罗嗦 - 使用下面的版本

        select day_of_the_week, count(1) days_count , pos
        from (
          select format_date('%A', day) day_of_the_week, format_date('%u', day) pos
          from `project.dataset.table`,
          unnest(generate_date_array(date(started_at_cst), date(ended_at_cst))) day
          where day between '2020-05-01' and '2021-04-30'
        )  
        group by day_of_the_week, pos
        order by pos
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-05-21
          • 1970-01-01
          • 2021-12-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-15
          • 1970-01-01
          相关资源
          最近更新 更多