我有以下查询:
WITH relationships AS (
SELECT related_user_id, count(*) AS trade_count
FROM trade_history
WHERE user_id = 487834568
GROUP BY related_user_id
ORDER BY trade_count DESC
)
SELECT offers.*,
relationships.trade_count
FROM offers
LEFT JOIN user_stock
ON user_stock.user_id = 487834568 and offers.product_id = user_stock.product_id
LEFT JOIN relationships
ON offers.user_id = relationships.related_user_id
WHERE offers.state = 'OPEN'
AND offers.user_id != 487834568
AND offers.group BETWEEN 1 AND 3
ORDER BY offers.created_at,
relationships.trade_count DESC,
user_stock.amount NULLS FIRST;
该查询向我显示所有报价并通过以下方式订购它们:
- 首先显示较旧的优惠
- 首先显示交易数量较高的报价(两个用户互相交易)
- 用户库存
我还需要将结果限制为最多 3 个product_id
。我做了一些谷歌搜索,发现这应该可以通过使用row_number()
和横向连接的窗口函数来实现。我不想使用row_number()
,因为表格包含很多条目,我很可能会遇到性能问题。我猜横向连接是正确的工具(在这里阅读http://charlesnagy.info/it/postgresql/group-by-limit-per-group-in-postgresql)但我无法以我有限的 SQL 知识得到一个像样的结果.
如何以高效的方式进行分组?
编辑:为了更清楚,我使用窗口函数实现了解决方案:
WITH relationships AS (
SELECT related_user_id, count(*) AS trade_count
FROM trade_history
WHERE user_id = 487834568
GROUP BY related_user_id
ORDER BY trade_count DESC
)
SELECT * FROM (
SELECT
offers.*,
relationships.trade_count,
row_number() OVER (
PARTITION BY resource_id
ORDER BY
offers.created_at,
relationships.trade_count DESC,
user_stock.amount NULLS FIRST
) AS row_number
FROM offers
LEFT JOIN user_stock
ON user_stock.user_id = 487834568 and offers.product_id = user_stock.product_id
LEFT JOIN relationships
ON offers.user_id = relationships.related_user_id
WHERE offers.state = 'OPEN'
AND offers.user_id != 487834568
AND offers.group BETWEEN 1 AND 3
ORDER BY row_number
) AS ordered_offers
WHERE ordered_offers.row_number <= 3;