我基本上有一张带有date
, timestamp
, DID
,的表coordinates
。
我想要一个查询,该查询将返回包含第 X 天的最后一个坐标、第 X+1 天的第一个坐标以及坐标的行。所以它只会返回有 2 个连续日期的结果。
这就是我想出的。一直试图让这个查询工作,它几乎是完美的,但我只需要添加注释掉的where
条件,它就会完全符合我的要求。但是当我取消注释时,我收到一个错误“列不存在”:
SELECT a.timestamp_intersecting_date d1,b.timestamp_intersecting_date d2,
a."DID",
a.timestamp_intersecting_max t1, b.timestamp_intersecting_min t2,
RANK () OVER (
PARTITION BY a.timestamp_intersecting_date
ORDER BY a.timestamp_intersecting_max DESC
) timestamp_d1_rank ,
RANK () OVER (
PARTITION BY b.timestamp_intersecting_date
ORDER BY b.timestamp_intersecting_max ASC
) timestamp_d2_rank,
a.coords_centroid, b.coords_centroid
FROM
signals a
INNER JOIN signals b ON (a."DID" = b."DID")
WHERE (b.timestamp_intersecting_date = a.timestamp_intersecting_date + INTERVAL '1 DAY')
AND a."DID" = b."DID"
--AND timestamp_d1_rank = 1
--AND timestamp_d2_rank = 1
ORDER BY a."DID", t1 desc, t2 asc
Run Code Online (Sandbox Code Playgroud)
如何解决这个问题?
不能在WHERE
子句中使用别名,也不能使用窗口函数。
为了进行演示,请考虑这个示例(fiddle)。
\n\nCREATE TABLE payment (amount INTEGER, pay_date DATE);\n\nINSERT INTO payment VALUES (54, \'2019-09-01\'), (56, \'2019-09-01\'), (154, \'2019-09-02\'), \n(156, \'2019-09-02\'), (254, \'2019-09-03\'), (256, \'2019-09-03\');\n
Run Code Online (Sandbox Code Playgroud)\n\n然后运行以下两个查询:
\n\nSELECT \n *, \n SUM(amount) OVER (PARTITION BY pay_date) AS the_sums\nFROM payment\nWHERE the_sums > 200; -- ERROR: column "the_sums" does not exist\n
Run Code Online (Sandbox Code Playgroud)\n\n和
\n\nSELECT \n *, \n SUM(amount) OVER (PARTITION BY pay_date) AS the_sums\nFROM payment\nWHERE SUM(amount) OVER (PARTITION BY pay_date) > 200;\n-- ERROR: window functions are not allowed in WHERE\n
Run Code Online (Sandbox Code Playgroud)\n\n您没有发布错误消息或 PostgreSQL 版本,但您的问题是 和timestamp_d1_rank
是timestamp_d2_rank
别名。
您有两个选择:
\n\nSELECT * FROM\n(\nSELECT \n *, \n SUM(amount) OVER (PARTITION BY pay_date) AS the_sums\nFROM payment\n) AS tab\nWHERE the_sums < 200;\n
Run Code Online (Sandbox Code Playgroud)\n\n结果:
\n\namount pay_date the_sums\n 54 2019-09-01 110\n 56 2019-09-01 110\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n有关整个区域的详细解释,请参见此处。
\n您不能在子句中使用窗口/排名函数或其别名,WHERE
因为它们在 , 中进行评估SELECT
,然后再WHERE
进行 评估。
WHERE
在评估窗口函数后,您可以使用子查询(派生表或 CTE)来处理第二个子句:
SELECT d1, d2,
"DID",
t1, t2,
coords_centroid_a,
coords_centroid_b
FROM
(
SELECT a.timestamp_intersecting_date d1, b.timestamp_intersecting_date d2,
a."DID",
a.timestamp_intersecting_max t1, b.timestamp_intersecting_min t2,
RANK () OVER (
PARTITION BY a.timestamp_intersecting_date
ORDER BY a.timestamp_intersecting_max DESC
) timestamp_d1_rank ,
RANK () OVER (
PARTITION BY b.timestamp_intersecting_date
ORDER BY b.timestamp_intersecting_max ASC
) timestamp_d2_rank,
a.coords_centroid AS coords_centroid_a,
b.coords_centroid AS coords_centroid_b
FROM
signals a
INNER JOIN signals b ON (a."DID" = b."DID")
WHERE (b.timestamp_intersecting_date = a.timestamp_intersecting_date + INTERVAL '1 DAY')
AND a."DID" = b."DID"
) AS t
WHERE t.timestamp_d1_rank = 1
AND t.timestamp_d2_rank = 1
ORDER BY "DID", t1 DESC, t2 ASC ;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1000 次 |
最近记录: |