SQL查询:EXTRACT(DATE FROM时间戳)与WHERE时间戳之间的差异

时间:2019-08-13 03:19:07

标签: sql google-bigquery

我要查询的是在给定日期范围内全天平均每小时的旅行次数。

使用时间戳数据的这两个函数之间到底有什么区别,有人可以解释为什么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,其余的结果完全相同。

2 个答案:

答案 0 :(得分:1)

我认为问题出在trip_start_timestamp > '2017-01-01'
要纠正差异,您应该使用trip_start_timestamp >= '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     

答案 1 :(得分:0)

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

用户Mikhail Berlyant给出了部分解决方案,即您将>=>混合在一起,因此您有两个不同的查询并将苹果与橙子进行比较。

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

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

但是,如果您在两端都进行>,则不会得到相同的结果。 (11409890与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-012017-01-01 00:00:00
  3. 当我们将底值与隐含精度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中提供的最小,可重现,可行的示例文档。