SQL 查询:EXTRACT(DATE FROM timestamp) 与 WHERE 时间戳之间的区别

Posted

技术标签:

【中文标题】SQL 查询:EXTRACT(DATE FROM timestamp) 与 WHERE 时间戳之间的区别【英文标题】:SQL query: Difference between EXTRACT(DATE FROM timestamp) vs. WHERE timestamp 【发布时间】: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'' 中将 '>' 更改为 '>=' 【参考方案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
    在第一个语句中,我们说2017-01-01 00:15:00 大于2017-01-01 00:00:00(隐含额外的小时/分钟/秒精度) 在第二个语句中,您可以看到您的价值底线(2017-01-012017-01-01 00:00:00 隐含精确度) 当我们比较给定值和隐含精度中的因子 2017-01-01 00:00:00 > 2017-01-01 00:15:00 时,您返回 false,因此您排除了同一天的任何记录。 2017-01-01 06:15:002017-01-01 22:15:00

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

【讨论】:

以上是关于SQL 查询:EXTRACT(DATE FROM timestamp) 与 WHERE 时间戳之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL Pivot -- 获取行总计

GreenPlum SQL 到 HiveSQL 的查询语句迁移

sql如何按日期中的月份查询

PL/SQL:如何遍历 sql extract() 结果

sql怎么只查询出日期第二大的记录啊 表名book 字段比如 bookname ,date 望指点啊

优化使用日期进行过滤和连接的 SQL 查询