0

我有以下查询:

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;
4

1 回答 1

1

如果您可以在那里添加一些分组,请在和HAVING count(offers.product_id) <= 3之间添加WHEREORDER BY

综上所述,感觉是对的。我将尝试基于不同的本地数据库进行类似的分组,看看它是否按我的预期工作,如果没有,将更新。

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
LEFT JOIN (
  SELECT array_agg(offers.id) AS ids
  FROM offers
  JOIN user_stock ON
    user_stock.user_id = 487834568 AND
    offers.user_id = user_stock.user_id AND
    offers.product_id = user_stock.product_id
  GROUP BY offers.user_id
  HAVING count(offers.id) <= 3
) AS offers_limit ON
  offers.id = any(offers_limit.ids)
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
于 2020-09-25T14:20:33.007 回答