【发布时间】:2021-05-22 01:42:37
【问题描述】:
我正在尝试做一些类似的事情
SELECT id, sum(weight) OVER w
FROM foo
-- Use random() to break ties
WINDOW w AS (ORDER BY weight DESC, random())
ORDER BY w
LIMIT 1;
但它出错了
ERROR: column "w" does not exist
LINE 5: ORDER BY w
我当然可以改写成
SELECT id, sum(weight) OVER w
FROM foo
-- Use random() to break ties
WINDOW w AS (ORDER BY weight DESC, random())
ORDER BY weight DESC, random()
LIMIT 1;
但除了缩短查询(我正在处理的完整查询要复杂得多,并且在 w 上具有多个窗口函数)之外,我还想捕获用于计算 @ 的相同 random() 排序987654328@,而不是让 PostgreSQL 生成不同的随机决胜局。
这是a DB fiddle,展示了我正在处理的数据集类型。我想确保查询输出中的第二列总是单调递增的。是否保证这样做,或者在这个简单的综合示例中只是碰巧这样做?我的真实查询有很多横向连接,实际上这些连接是为了阻止优化器从其中提升常量,所以我不确定它是否会一直成立。
编辑:正如@laurenz-albe 指出的那样,这是不可能的。然而,在我的具体情况下,我意识到我已经有一个可以直接排序的值,在sum(weight),like in this fiddle。
【问题讨论】:
-
我不确定您是否可以在不使用动态 SQL 的情况下从 Postgres 执行此操作(即编写代码来生成您的 SQL 语句)。但是,你为什么需要这个?我认为明确重写
ORDER BY子句实际上更易于阅读和维护。 -
@TimBiegeleisen:因为我试图获得与计算
sum(weight)相同的顺序。如果我输入两次,我希望 PostgreSQL 会生成两个不同的顺序并随机打破平局。因为我知道事实上我有很多关系,所以获得相同的订单很重要。 -
添加示例数据来解释此处的逻辑可能会有所帮助。至少,有人可能会为您提供您想要的解决方法。
-
@TimBiegeleisen:说得好,完成了。
-
而且,我意识到我可以通过
sum(weight)订购并将其用作生成的订单的代理,所以我想我的具体问题可以轻松简洁地解决。
标签: sql postgresql sql-order-by window-functions