lra*_*rai 3 postgresql order-by sorting limits group-by
我有一个返回所需输出的查询。
SELECT
shop,
JSON_AGG(item_history.* ORDER BY created_date DESC) as data
FROM item_history
GROUP BY
shop;
Run Code Online (Sandbox Code Playgroud)
结果:
[
{
"shop": "shop1",
"data": [
{
"id": 226,
"price": "0",
"shop": "shop1.com",
"country": "UK",
"item": "item1",
"created_date": "2021-06-07T08:48:42.338201",
},
{
"id": 224,
"price": "0",
"shop": "shop1.com",
"country": "UK",
"item": "item 1",
"created_date": "2021-06-07T07:53:25.030621",
},
...
},
{
"shop": "shop2",
"data": [
{
"id": 225,
"price": "0",
"shop": "shop2.com",
"country": "DE",
"item": "Item 2",
"created_date": "2021-06-07T08:48:36.443849",
},
...
]
Run Code Online (Sandbox Code Playgroud)
这正是我想要的输出,但问题是它获取data
数组下的所有项目,最好限制该数组。我尝试添加LIMIT
SELECT
shop,
JSON_AGG(item_history.* ORDER BY created_date DESC LIMIT 5) as data
FROM item_history
GROUP BY
shop;
Run Code Online (Sandbox Code Playgroud)
但我明白了syntax error at or near "limit"
。是否可以限制 的输出JSON_AGG
?
ORDER BY
里面的语法JSON_AGG
不接受LIMIT
选项。我不知道有什么方法可以以这种方式限制任何聚合函数的范围。作为替代方案,您可以尝试以下ROW_NUMBER
+FILTER
方法:
shop
分配分区内的行号在 SQL 中它看起来像这样:
SELECT
shop,
JSON_AGG(derived.* ORDER BY created_date DESC) FILTER (WHERE rn <= 5) AS data
FROM
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY shop ORDER BY created_date DESC) AS rn
FROM
item_history
) AS derived
GROUP BY
shop;
Run Code Online (Sandbox Code Playgroud)
或者您可以使用 CTE 而不是派生表:
WITH
cte AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY shop ORDER BY created_date DESC) AS rn
FROM
item_history
)
SELECT
shop,
JSON_AGG(cte.* ORDER BY created_date DESC) FILTER (WHERE rn <= 5) AS data
FROM
cte
GROUP BY
shop;
Run Code Online (Sandbox Code Playgroud)
结果是相同的。差异(如果有的话)仅在于效率,因为 PostgreSQL 中的 CTE 可能会具体化,而派生表通常不会具体化。您应该亲自测试一下,看看哪个选项更适合您。
注意:在这两种情况下,聚合函数仍然具有相同的ORDER BY
,但您现在可以根据需要更改它,或者完全删除它:该FILTER
子句确保您无论如何都只有最后五个条目shop
。
归档时间: |
|
查看次数: |
8548 次 |
最近记录: |