【问题标题】:SQL query: Difference between EXTRACT(DATE FROM timestamp) vs. WHERE timestampSQL 查询:EXTRACT(DATE FROM timestamp) 与 WHERE 时间戳之间的区别
【发布时间】:2019-08-13 03:19:07
【问题描述】:

我正在查询给定日期范围内一天中每小时平均每小时的行程次数。

这两个处理时间戳数据的函数之间到底有什么区别,有人可以解释一下为什么 num_trips 列中的第一个值不同吗?见下文

   (
   SELECT EXTRACT(HOUR FROM trip_start_timestamp) AS hour_of_day, 
   trip_seconds, trip_miles
   FROM `bigquery-public-data.chicago_taxi_trips.taxi_trips`
   WHERE EXTRACT(DATE FROM trip_start_timestamp) >= '2017-01-01'
   AND EXTRACT(DATE FROM trip_start_timestamp) < '2017-07-01'
           AND trip_seconds > 0 
           AND trip_miles > 0
       )
       SELECT hour_of_day, 
       COUNT(1) as num_trips,
       (3600 * SUM(trip_miles) / SUM(trip_seconds)) as avg_mph
               FROM RelevantRides1
               GROUP BY hour_of_day
               ORDER BY hour_of_day 

   (
   SELECT EXTRACT(HOUR FROM trip_start_timestamp) AS hour_of_day, 
   trip_miles, trip_seconds
   FROM `bigquery-public-data.chicago_taxi_trips.taxi_trips`
                   WHERE trip_start_timestamp > '2017-01-01' AND 
                         trip_start_timestamp < '2017-07-01' AND 
                         trip_seconds > 0 AND 
                         trip_miles > 0
         )
         SELECT hour_of_day, 
         COUNT(1) AS num_trips, 
         3600 * SUM(trip_miles) / SUM(trip_seconds) AS avg_mph
             FROM RelevantRides
             GROUP BY hour_of_day
             ORDER BY hour_of_day

我希望两个查询都返回相同的结果,但是当我打印数据帧时,第一个查询在一天的第一个小时内给出了不同的 num_trips 结果,我使用了Extract,其余的结果是相同的.

【问题讨论】:

  • 请发布您的输入和上述查询的输出。
  • 在 'trip_start_timestamp > '2017-01-01'' 中将 '>' 更改为 '>='

标签: sql google-bigquery


【解决方案1】:

我认为问题出在trip_start_timestamp &gt; '2017-01-01'
要解决差异,您应该使用trip_start_timestamp &gt;= '2017-01-01'

下面的简化示例重现了问题

#standardSQL
WITH `project.dataset.table` AS (
  SELECT CURRENT_TIMESTAMP() trip_start_timestamp UNION ALL
  SELECT TIMESTAMP_TRUNC(TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY), DAY) UNION ALL
  SELECT TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 2 DAY)
)
SELECT trip_start_timestamp
FROM `project.dataset.table`
WHERE trip_start_timestamp > '2019-08-12'

返回

Row trip_start_timestamp     
1   2019-08-13 05:04:34.747114 UTC   

同时

SELECT trip_start_timestamp
FROM `project.dataset.table`
WHERE trip_start_timestamp >= '2019-08-12'   

返回

Row trip_start_timestamp     
1   2019-08-13 05:05:38.784956 UTC   
2   2019-08-12 00:00:00 UTC     

【讨论】:

    【解决方案2】:

    所以我无法运行原始示例,因为如果我尝试使用bigquery-public-data.chicago_taxi_trips 表将查询复制粘贴到新项目中,则会得到Syntax error: Unexpected keyword SELECT at [10:8]。也就是说,我将尝试使用给出的第一个选择语句来回答......

    用户 Mikhail Berlyant 给出了部分解决方案,即您将 &gt;= 和 &gt; 混合使用,因此您有两个不同的查询,并且正在比较苹果和橙子。

    如果您运行以下查询,您会注意到返回的记录数相同。

    SELECT count(*) from
     (
      SELECT 
        EXTRACT(HOUR FROM trip_start_timestamp) AS hour_of_day, 
        trip_seconds, trip_miles
      FROM `bigquery-public-data.chicago_taxi_trips.taxi_trips`
      WHERE EXTRACT(DATE FROM trip_start_timestamp) >= '2017-01-01'
        AND EXTRACT(DATE FROM trip_start_timestamp) < '2017-07-01'
        AND trip_seconds > 0 
        AND trip_miles > 0
     ) t;
    -- returns 11460748
    
    SELECT count(*) from 
    (
       SELECT EXTRACT(HOUR FROM trip_start_timestamp) AS hour_of_day, 
       trip_miles, trip_seconds
       FROM `bigquery-public-data.chicago_taxi_trips.taxi_trips`
      WHERE trip_start_timestamp >= '2017-01-01' 
        AND trip_start_timestamp < '2017-07-01'  
        AND trip_seconds > 0 AND 
        trip_miles > 0
    ) t1
    -- returns 11460748
    

    但是,如果您在两端都执行&gt;,则不会得到相同的结果。 (11409890 vs 11460748 那为什么?那是因为当您使用EXTRACT(DATE FROM trip_start_timestamp) 时,您会在比较之前先对字段进行定位。例如:

    select '2017-01-01 00:15:00' > '2017-01-01'; --true
    select extract(date from timestamp '2017-01-01 00:15:00'); --2017-01-01
    select extract(date from timestamp '2017-01-01 00:15:00') > '2017-01-01'; --false
    
    1. 在第一个语句中,我们说2017-01-01 00:15:00 大于2017-01-01 00:00:00(隐含额外的小时/分钟/秒精度)
    2. 在第二个语句中,您可以看到您的价值底线(2017-01-01 或 2017-01-01 00:00:00 隐含精确度)
    3. 当我们比较给定值和隐含精度中的因子 2017-01-01 00:00:00 > 2017-01-01 00:15:00 时,您返回 false,因此您排除了同一天的任何记录。 2017-01-01 06:15:00、2017-01-01 22:15:00等

    我建议使用here 提供的最小、可重现、可行的示例文档。

    【讨论】:

      猜你喜欢
      • 2016-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-14
      • 2012-02-29
      • 1970-01-01
      • 2015-08-17
      • 1970-01-01
      相关资源
      最近更新 更多