在PostgreSQL 9.1+中,我试图使用ROW_NUMBER()别名字段来过滤WHERE子句中的结果集。此查询工作正常:
SELECT inv.client_pk,
inv.invoice_pk, inv.contract_pk,
ROW_NUMBER() OVER ( PARTITION BY inv.client_pk ORDER BY inv.client_pk) as row_number
FROM controllr.client as cli
LEFT JOIN controllr.invoice as inv ON inv.client_pk = cli.client_pk
WHERE client_status != 3;
Run Code Online (Sandbox Code Playgroud)
但是,当我在“ WHERE”中添加“ row_number”时:
SELECT inv.client_pk,
inv.invoice_pk, inv.contract_pk,
ROW_NUMBER() OVER ( PARTITION BY inv.client_pk ORDER BY inv.client_pk) as row_number
FROM controllr.client as cli
LEFT JOIN controllr.invoice as inv ON inv.client_pk = cli.client_pk
WHERE client_status != 3
AND row_number <= 3;
Run Code Online (Sandbox Code Playgroud)
它给我一个错误:
列“ row_number”不存在
当字段“ row_number”作为别名字段明确存在时。
我做错了什么?
ps:我已经尝试过HAVING子句
使用子查询:
SELECT
*
FROM
(SELECT
inv.client_pk, inv.invoice_pk, inv.contract_pk,
ROW_NUMBER() OVER (PARTITION BY inv.client_pk ORDER BY inv.client_pk) AS row_number
FROM
controllr.client as cli
LEFT JOIN
controllr.invoice as inv ON inv.client_pk = cli.client_pk
WHERE
client_status != 3) AS sub
WHERE
row_number <= 3;
Run Code Online (Sandbox Code Playgroud)
使用CTE:
WITH cte AS
(
SELECT
inv.client_pk, inv.invoice_pk, inv.contract_pk,
ROW_NUMBER() OVER ( PARTITION BY inv.client_pk ORDER BY inv.client_pk) AS row_number
FROM
controllr.client as cli
LEFT JOIN
controllr.invoice as inv ON inv.client_pk = cli.client_pk
WHERE
client_status != 3
)
SELECT *
FROM cte
WHERE row_number <= 3;
Run Code Online (Sandbox Code Playgroud)
之所以收到该错误,是因为该WHERE子句在该SELECT子句之前被处理。因此,row_number在尝试... row_number <= 3使用原始查询处理条件时,引擎无法将其视为一列。
同样,使用CTE具有与使用子查询相同的性能,但是确实提高了可读性。
| 归档时间: |
|
| 查看次数: |
1328 次 |
| 最近记录: |