Postgres GROUP BY,然后排序
Postgres GROUP BY, then sort
我有一个数据库查询:
SELECT
Foo,
Foo2,
some_calc as Bar,
some_other_calc as Bar2,
From
FooBar
-- some inner joins for the calcs
GROUP BY FOO
ORDER BY Bar DESC, Bar2 DESC;
我想通过订单查询按数据库排序,然后将 FOO
组合在一起,以便第一个分组的块包含具有最大 Bar 的 FOO
。 FOO
s 的第二个分组块包含第二个最高的 Bar,等等
但这不起作用,因为 Postgres 不允许随机分组:
column "Bar" must appear in the GROUP BY clause or be used in an aggregate function
.
我该如何解决这个问题?
示例数据和输出:
╔═════╦══════════╦════╦════╦
║ FO ║ Bar ║ Bar 2 ║
╠═════╬══════════╬═════════╬
║ 6 ║ 10 ║ ║
║ 4 ║ 110 ║ ║
║ 3 ║ 120 ║ ║
║ 8 ║ 140 ║ ║
║ 3 ║ 180 ║ ║
║ 3 ║ 190 ║ ║
╚═════╩══════════╩════╩════╩
输出:
╔═════╦══════════╦════╦════╦
║ FO ║ Bar ║ Bar 2 ║
╠═════╬══════════╬═════════╬
║ 3 ║ 190 ║ ║
║ 3 ║ 180 ║ ║
║ 3 ║ 120 ║ ║
║ 8 ║ 140 ║ ║
║ 4 ║ 110 ║ ║
║ 6 ║ 10 ║ ║
╚═════╩══════════╩════╩════╩
你只要order by
。 Group by
通过聚合减少(通常)行数。
您可以使用 window 函数完成此操作:
SELECT Foo, Bar, Bar2,
From FooBar
ORDER BY MAX(Bar) OVER (PARTITION BY Foo) DESC,
Foo;
这不应该满足您的要求吗?
如果没有,如果您可以在查询中提供一些示例数据并显示您希望如何将其作为输出,将会有所帮助。
SELECT
Foo,
MAX(some_calc) as Bar,
MAX(some_other_calc) as Bar2,
From
FooBar
##some inner joins for the calcs
GROUP BY FOO;
SELECT foo, <some calc> AS bar, bar2
FROM foobar
ORDER BY max(<some calc>) OVER (PARTITION BY foo) DESC NULLS LAST -- can't refer to bar
, bar DESC NULLS LAST -- but you can here
, foo DESC NULLS LAST;
bar
不必是列,可以是任何有效的表达式,甚至是聚合函数(与 GROUP BY
组合)——只是不是另一个 window 函数,它不能嵌套。示例:
- PostgreSQL - Referencing another aggregate column in a window function
您不能,但是,在window 函数内的同一查询级别上引用列别名(输出列名)。您必须再次拼出表达式,或将计算移动到子查询或 CTE。
您 可以 引用 ORDER BY
和 GROUP BY
中的输出列名称,否则(但不能在 WHERE
或 HAVING
子句中)。解释:
- GROUP BY + CASE statement
- PostgreSQL Where count condition
由于尚未定义,我们必须期待 NULL 值。通常您最后需要 NULL 值,因此按降序添加 NULLS LAST
。参见:
- Sort by column ASC, but NULL values first?
假设您首先想要更大的 foo
,以防与 bar
相关。
我有一个数据库查询:
SELECT
Foo,
Foo2,
some_calc as Bar,
some_other_calc as Bar2,
From
FooBar
-- some inner joins for the calcs
GROUP BY FOO
ORDER BY Bar DESC, Bar2 DESC;
我想通过订单查询按数据库排序,然后将 FOO
组合在一起,以便第一个分组的块包含具有最大 Bar 的 FOO
。 FOO
s 的第二个分组块包含第二个最高的 Bar,等等
但这不起作用,因为 Postgres 不允许随机分组:
column "Bar" must appear in the GROUP BY clause or be used in an aggregate function
.
我该如何解决这个问题?
示例数据和输出:
╔═════╦══════════╦════╦════╦
║ FO ║ Bar ║ Bar 2 ║
╠═════╬══════════╬═════════╬
║ 6 ║ 10 ║ ║
║ 4 ║ 110 ║ ║
║ 3 ║ 120 ║ ║
║ 8 ║ 140 ║ ║
║ 3 ║ 180 ║ ║
║ 3 ║ 190 ║ ║
╚═════╩══════════╩════╩════╩
输出:
╔═════╦══════════╦════╦════╦
║ FO ║ Bar ║ Bar 2 ║
╠═════╬══════════╬═════════╬
║ 3 ║ 190 ║ ║
║ 3 ║ 180 ║ ║
║ 3 ║ 120 ║ ║
║ 8 ║ 140 ║ ║
║ 4 ║ 110 ║ ║
║ 6 ║ 10 ║ ║
╚═════╩══════════╩════╩════╩
你只要order by
。 Group by
通过聚合减少(通常)行数。
您可以使用 window 函数完成此操作:
SELECT Foo, Bar, Bar2,
From FooBar
ORDER BY MAX(Bar) OVER (PARTITION BY Foo) DESC,
Foo;
这不应该满足您的要求吗?
如果没有,如果您可以在查询中提供一些示例数据并显示您希望如何将其作为输出,将会有所帮助。
SELECT
Foo,
MAX(some_calc) as Bar,
MAX(some_other_calc) as Bar2,
From
FooBar
##some inner joins for the calcs
GROUP BY FOO;
SELECT foo, <some calc> AS bar, bar2
FROM foobar
ORDER BY max(<some calc>) OVER (PARTITION BY foo) DESC NULLS LAST -- can't refer to bar
, bar DESC NULLS LAST -- but you can here
, foo DESC NULLS LAST;
bar
不必是列,可以是任何有效的表达式,甚至是聚合函数(与 GROUP BY
组合)——只是不是另一个 window 函数,它不能嵌套。示例:
- PostgreSQL - Referencing another aggregate column in a window function
您不能,但是,在window 函数内的同一查询级别上引用列别名(输出列名)。您必须再次拼出表达式,或将计算移动到子查询或 CTE。
您 可以 引用 ORDER BY
和 GROUP BY
中的输出列名称,否则(但不能在 WHERE
或 HAVING
子句中)。解释:
- GROUP BY + CASE statement
- PostgreSQL Where count condition
由于尚未定义,我们必须期待 NULL 值。通常您最后需要 NULL 值,因此按降序添加 NULLS LAST
。参见:
- Sort by column ASC, but NULL values first?
假设您首先想要更大的 foo
,以防与 bar
相关。