为什么分区需要嵌套选择?

时间:2013-08-15 08:41:54

标签: sql postgresql

我有一个页面显示每个用户的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关键字。

4 个答案:

答案 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 topicthis one有关SQL执行SELECT子句的顺序。我认为它不仅适用于PostgreSQL,也适用于所有RDBMS。