2016-08-27 81 views
0

我有這樣如何檢測重疊的時間範圍在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 

一切工作正常,這個階段後,我要查詢行,他們的時間是開始時間和結束時間之間在另一方面,他們OV字erlap。我已經發現了這個問題

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表,但我不知道如何,能否請您給我有些提示?

+0

別名'爲startTime'在內部查詢中不可見。將它推入子查詢並加入。 (或使用CTE)(臨時視圖也可以工作) – wildplasser

+0

爲什麼查詢中的startTime> endTime?我的意思是你正在做的操作是添加/減少間隔。 –

+0

@wildplasser對不起,但我無法弄清楚你的意思,你能給我舉個例子嗎?謝謝 –

回答

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") 
     ; 
+0

非常感謝,但我得到這個錯誤錯誤:列「位置類型」指定不止一次有什麼錯? –

+0

感謝您的提示,它們對我非常有用 –

+0

您在''位置類型''中添加了'...',您需要用'f1.'或'f2.'作爲其前綴,但是它們反正是一樣的) – wildplasser