我有一张像这样的表arrivals
:
HHMM Car
---- ---
0001 01
0001 02
0001 03
0002 04
...
0029 20
0029 21
0030 22
...
0059 56
我需要知道在30分钟的每个范围内有多少辆车到达。 我写了一个这样的查询:
WITH
PREVIOUS_QUERIES AS
(
-- in fact, "PREVIOUS_QUERIES" represent a sequence of queries where I get
-- the timestamp HHMM and convert it in a range where HOURS = HH and
-- MINUTES_START can be 0 (if MM<30) or 30 (if MM>=30).
),
INTERVALS AS
(
SELECT
TO_CHAR(HOURS,'FM00')||':'||TO_CHAR(MINUTES_START,'FM00')||' - '
||TO_CHAR(HOURS,'FM00')||':'||TO_CHAR(MINUTES_START +29,'FM00') AS INTERVAL,
CAR
FROM
PREVIOUS_QUERIES
)
SELECT
INTERVAL,
COUNT (DISTINCT (CAR)),
FROM INTERVALS
GROUP BY INTERVAL
ORDER BY INTERVAL
;
我的查询产生以下结果。
Interval Cars
------------- ----
00:00 - 00:29 21
00:30 - 00:59 35
01:00 - 01:29 41
02:30 - 02:59 5
03:00 - 03:29 12
03:30 - 03:59 13
...
这意味着,如果在某个时间间隔内没有到达,我的查询不会显示Cars = 0的行。我在结果中需要这些行:
01:30 - 01:59 0
02:00 - 02:29 0
我怎样才能添加这些行?可以通过更改我的查询来完成,或者 该查询是否应该完全重写?
我想象的是我应该从'00:00-00:29'到'23:30-23:59'生成30分钟的48个范围,然后将它们用作SELECT的参数,但我不知道我知道怎么做。
答案 0 :(得分:0)
您可以将这48个值选择到另一个CTE中,例如'cteIntervals',然后将最终查询调整为:
SELECT
I.Interval
, NVL(Q.Cars, 0) Cars
FROM
cteIntervals I
LEFT JOIN
(
-- Your current query
) Q
ON I.Interval = Q.Interval
这具有为最终查询创建模板的效果。
对于稍微更动态的解决方案,您可以考虑使用递归CTE生成cteIntervals
,或者您可以将值存储在表等中。