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 > '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
【讨论】:
【参考方案2】:所以我无法运行原始示例,因为如果我尝试使用bigquery-public-data.chicago_taxi_trips
表将查询复制粘贴到新项目中,则会得到Syntax error: Unexpected keyword SELECT at [10:8]
。也就是说,我将尝试使用给出的第一个选择语句来回答......
用户 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 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-01
或 2017-01-01 00:00:00
隐含精确度)
当我们比较给定值和隐含精度中的因子 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 提供的最小、可重现、可行的示例文档。
【讨论】:
以上是关于SQL 查询:EXTRACT(DATE FROM timestamp) 与 WHERE 时间戳之间的区别的主要内容,如果未能解决你的问题,请参考以下文章
GreenPlum SQL 到 HiveSQL 的查询语句迁移