Sql 使用子查询进行左连接,不将空结果返回为";0“;

Sql 使用子查询进行左连接,不将空结果返回为";0“;,sql,postgresql,Sql,Postgresql,我正在写一个查询,搜索一个停车罚单数据库,并统计每一刻钟有多少罚单被发出 这里有两个活动部件。子查询使用generate_series生成15分钟增量时间戳,并将其存储为“timestep”。然后,外部查询使用另一个timestamp语句进行连接,该语句将所有内容舍入到最低的四分之一小时 现在,它不会将空结果返回为“0”,这正是我试图通过连接实现的 从本质上讲,我在寻找这样的输出: 12:00: 0 12:15: 10 12:45: 5 13:00: 0 我认为问题在于您将违规表作为左侧表,因此

我正在写一个查询,搜索一个停车罚单数据库,并统计每一刻钟有多少罚单被发出

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

现在,它不会将空结果返回为“0”,这正是我试图通过连接实现的

从本质上讲,我在寻找这样的输出:

12:00: 0 12:15: 10 12:45: 5 13:00: 0
我认为问题在于您将违规表作为左侧表,因此它是加入时间步长结果集的基础。如果没有违规记录,它不在乎时间步长结果中是否有条目

我倒过来,所以你的左边桌子是时间步长的,所以你总是得到所有15分钟的间隔。。。然后左键加入到违规操作中。如果没有违规记录,它应该保留时间段,但在您查找时为零

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 

您的
左连接的switcheroo已清除。此外,我建议使用更简单、更快的查询:

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
选择step::time作为timestep,count(*)作为ct
从生成_系列('2000-1-1 00:00'::时间戳
,'2000-1-123:45'::时间戳
,“15分钟”::间隔)作为t(步长)
左连接冲突
在v.“InfractionTime”::time>=t.step::time
和v.“违规时间”::时间
  • 这使用了直接与时间戳一起工作的第二种形式。不过,时间不是这样的,所以我花了一天的时间将结果转换为时间(非常便宜!)

  • 重写后的查询用于连接,因此,如果查询表的较小样本,可以使用“InfractionTime”上的普通索引来产生很大的效果。只要查询整个表,Postgres将使用顺序扫描


您可能希望将其设置为一个
连接(而非左)或颠倒顺序:
从(…)开始,因为计时器左连接违反了…
。并将
COUNT(*)
更改为:
COUNT(违规。“违规时间”)
COUNT()从不返回null。如果希望0显示为null,则使用每季度发出的NullIf(Count(*),0)
。。
:30
步骤在哪里?
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