在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;
但是当我在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;
它给了我一个错误:
列“row_number”不存在
当字段“row_number”明显作为别名字段存在时。
我做错了什么?
ps:我已经尝试过HAVING子句
答案 0 :(得分:4)
使用子查询:
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;
使用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;
您收到该错误的原因是因为在WHERE
子句之前处理了SELECT
子句。因此,在尝试使用原始查询处理条件row_number
时,引擎无法将... row_number <= 3
视为列。
此外,使用CTE与使用子查询具有相同的性能,但它确实提高了可读性。
答案 1 :(得分:2)
使用子查询:
SELECT client_pk, invoice_pk, contract_pk
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
) t
WHERE row_number <= 3;