LEFT JOIN使用子查询不返回null结果为“0”

时间:2013-12-01 08:00:00

标签: sql postgresql

我正在编写一个查询停车票数据库的查询,并计算每季度发布的停车票数量。

这里有两个活动部件。子查询使用generate_series生成15分钟的增量时间戳,并将其存储为“timestep”。然后外部查询使用另一个时间戳语句连接,该语句将所有内容舍入到最低的四分之一小时。

现在,它没有将null结果返回为“0”,这正是我试图通过连接完成的。

基本上,我正在寻找这样的输出:

12:00: 0
12:15: 10
12:45: 5
13:00: 0

......等等。

SELECT count(*), timer.timestep
FROM violations
left join (SELECT (hourstep || ':' || minutestep)::time AS timestep 
    from generate_series(0,23) AS hourstep, 
    generate_series(0,59, 15) AS minutestep) 
 AS timer 

ON timer.timestep = 
(extract(hour from violations."InfractionTime") 
|| ':' || 
((extract(minute FROM violations."InfractionTime")::int / 15)*15))::time

GROUP BY timer.timestep 

2 个答案:

答案 0 :(得分:2)

我认为问题在于您将VIOLATIONS表作为左侧表,因此它是加入您的时间步结果集的基础。如果没有违规记录,则不关心您的时间步骤结果是否有条目。

我反转,所以你的LEFT-SIDE表是时间步的表,所以你总是得到所有15分钟的间隔...然后LEFT JOIN到违规。如果违规中没有记录,则应该保留时间段,但是如您所查找的那样为零。

SELECT 
      timer.timestep, 
      count(*)
   FROM 
      ( SELECT 
              (hourstep || ':' || minutestep)::time AS timestep
           from 
              generate_series(0,23) AS hourstep, 
              generate_series(0,59, 15) AS minutestep) AS timer 
        LEFT JOIN violations
           ON timer.timestep = 
              (extract(hour from violations."InfractionTime") 
              || ':' || 
              ((extract(minute FROM violations."InfractionTime")::int / 15)*15))::time
   group by
      timer.timestep 

答案 1 :(得分:0)

LEFT JOIN的切换台已经被清除。另外我建议更简单,更快查询:

SELECT step::time AS timestep, count(*) AS ct
FROM   generate_series('2000-1-1 00:00'::timestamp
                     , '2000-1-1 23:45'::timestamp
                     , '15 min'::interval ) AS t(step)
LEFT   JOIN violations v
         ON v."InfractionTime"::time >= t.step::time
        AND v."InfractionTime"::time <  t.step::time + interval '15 min'
GROUP  BY 1
ORDER  BY 1
  • 这使用了generate_series()的第二种形式,可以直接使用时间戳。但不是time,所以我参加了一个分期日并将结果投入时间(非常便宜!)

  • 重写的查询使用sargable expressions进行连接,因此,如果查询表的较小样本,可以使用“InfractionTime”上的普通索引产生很好的效果。只要您查询整个表格,Postgres就会使用顺序扫描。

相关问题