如何检测PostgreSQL

时间:2016-08-27 19:20:38

标签: postgresql

我有一张这样的表

CREATE TABLE public.userlocation
(
  datetime timestamp with time zone,
  location geometry,
  locationtype integer,
  buffer double precision,
  timebuffer double precision,
  "userID" numeric,
  "ID" integer NOT NULL DEFAULT nextval('"userlocation_ID_seq"'::regclass),
  "time" time with time zone
)

每行都有一个时间,然后是一个值来制作动态时间范围,实际上如果time=8timebuffer=15那么时间范围是endTime= 8+15minstartTime= 8-15 min。我只需使用此查询即可完成此操作

select f1.*,f1.time +(f1.timebuffer::text||' minute')::INTERVAL as startTime,f1.time-(f1.timebuffer::text||' minute')::INTERVAL as endTime

一切正常,在这个阶段之后,我想查询它们的时间段在startTime和endTime之间的行,而在其他单词中它们重叠。我已经找到了这个问题

PostgreSQL query to detect overlapping time ranges

但这里有一点不同,我没有开始时间和结束时间所以我必须使用上面的方法创建它们。所以野兔是我的查询

    select f1.*,f1.time -(f1.timebuffer::text||' minute')::INTERVAL as startTime,f1.time+(f1.timebuffer::text||' minute')::INTERVAL as endTime
from userlocation f1
where exists (select f2.time -(f2.timebuffer::text||' minute')::INTERVAL as startTime,f2.time+(f2.timebuffer::text||' minute')::INTERVAL as endTime
              from userlocation f2
              where tsrange(f2.startTime, f2.endTime, '()') && tsrange(f1.startTime, f1.endTime, '()')
                and f2.locationtype = f1.locationtype
                and f2.locationtype=1
                and f2."ID" <> f1."ID");

但是我收到了这个错误

[2016-08-27 23:42:45] [42703] ERROR: column f2.starttime does not exist

职位:372

我想起初我应该创建F2表但我不知道怎么样,你能给我一些提示吗?

1 个答案:

答案 0 :(得分:1)

  • 首先:列别名(select expression AS somename)无法在查询中使用,只能从外部查询中看到。您可以通过将其包装到(subquery) xx或视图或CTE

  • 中来解决此问题
  • 第二:不要重复自己:如果你需要计算两次相同的表达式,你可能会做太多......

CREATE TEMP VIEW omg AS
        SELECT fx.*,fx.time -(fx.timebuffer::text||' minute')::INTERVAL as startTime
        ,fx.time+(fx.timebuffer::text||' minute')::INTERVAL as endTime
        , fx.locationtype
        , fx.ID
        -- ... maybe more columns and expressions ...
        FROM userlocation fx
        ;


SELECT f1.startTime, f1.endTime
        -- ... maybe more columns and expressions ...
FROM omg f1 
WHERE EXISTS (
   SELECT 1
   FROM omg f2
   WHERE tsrange(f2.startTime, f2.endTime, '()') && tsrange(f1.startTime, f1.endTime, '()')
   AND f2.locationtype = f1.locationtype
   AND f2.locationtype=1
   AND f2."ID" <> f1."ID")
        ;
  • 而不是视图,你可以使用CTE(视图可能表现更好)
  • 你也可以将tsrange拉入视图或CTE
  • 我没有检查逻辑

为了完整性,CTE版本(几乎看起来相同)

WITH omg AS (
        SELECT fx.*,fx.time -(fx.timebuffer::text||' minute')::INTERVAL as startTime
        ,fx.time+(fx.timebuffer::text||' minute')::INTERVAL as endTime
        , fx.locationtype
        , fx.ID
        -- ... maybe more columns and expressions ...
        FROM userlocation fx
        )
SELECT f1.startTime, f1.endTime
        -- ... maybe more columns and expressions ...
FROM omg f1 
WHERE EXISTS (
   SELECT 1
   FROM omg f2
   WHERE tsrange(f2.startTime, f2.endTime, '()') && tsrange(f1.startTime, f1.endTime, '()')
   AND f2.locationtype = f1.locationtype
   AND f2.locationtype=1
   AND f2."ID" <> f1."ID")
        ;