0

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

4 回答 4

7

它似乎与任何查询都是相同的“规则”,列别名对WHERE子句不可见;

这也会失败;

SELECT id AS newid
FROM test
WHERE newid=1;     -- must use "id" in WHERE clause
于 2013-08-15T08:44:42.313 回答
4

SQL查询如:

SELECT *
FROM table
WHERE <condition>

将按下一个顺序执行:

3.SELECT *
1.FROM table
2.WHERE <condition>

因此,正如 Joachim Isaksson 所说,由于处理顺序,子句中的列在SELECt子句中不可见。WHERE

在您的第二个查询中,列首先row_num在子句中获取FROM,因此它将在WHERE子句中可见。

以下是它们执行顺序的简单步骤列表。

于 2013-08-15T08:48:40.130 回答
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子句中允许它们才能解决问题。

于 2013-08-15T10:32:49.927 回答
0

您可以在 dba.stockexchange.com 上查看这个主题这个主题,了解 SQL 执行 SELECT 子句的顺序。我认为它不仅适用于 PostgreSQL,而且适用于所有 RDBMS。

于 2013-08-15T08:57:55.777 回答