我有一个页面显示每个用户的10条消息(不要问我为什么)
我有以下代码:
SELECT *, row_number() over(partition by user_id) as row_num
FROM "posts"
WHERE row_num <= 10
它不起作用。
当我这样做时:
SELECT *
FROM (
SELECT *, row_number() over(partition by user_id) as row_num FROM "posts") as T
WHERE row_num <= 10
确实有效
为什么我需要嵌套查询才能看到row_num
列?顺便说一句,在第一个请求中,我实际上在结果中看到了它,但是不能在此列中使用where
关键字。
答案 0 :(得分:7)
它似乎与任何查询都是相同的“规则”,WHERE
子句不能看到列别名;
这也会失败;
SELECT id AS newid
FROM test
WHERE newid=1; -- must use "id" in WHERE clause
答案 1 :(得分:4)
SQL查询如:
SELECT *
FROM table
WHERE <condition>
将按下一个顺序执行:
3.SELECT *
1.FROM table
2.WHERE <condition>
所以,正如Joachim Isaksson所说,SELECt
子句中的列在WHERE
子句中不可见,因为处理顺序。
在第二个查询中,首先在row_num
子句中提取列FROM
,因此它将在WHERE
子句中显示。
Here是执行顺序的简单步骤列表。
答案 2 :(得分:2)
标准SQL中有这个规则的理由很充分。
考虑声明:
SELECT *, row_number() over (partition by user_id) as row_num
FROM "posts"
WHERE row_num <= 10 and p.type = 'xxx';
p.type = 'xxx'
何时相对于行号进行评估?换句话说,这会返回前十行“xxx”吗?或者它会在前十行中返回“xxx”吗?
SQL语言的设计者认识到这是一个难以解决的问题。仅在select
子句中允许它们才能解决问题。
答案 3 :(得分:0)
您可以在dba.stockexchange.com上查看this topic和this one有关SQL执行SELECT子句的顺序。我认为它不仅适用于PostgreSQL,也适用于所有RDBMS。