我有一张这样的表
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=8
和timebuffer=15
那么时间范围是endTime= 8+15min
和startTime= 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表但我不知道怎么样,你能给我一些提示吗?
答案 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版本(几乎看起来相同)
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")
;