我想在Postgres中运行一个查询,按预期返回结果集(比如SELECT * FROM products ORDER BY created_at DESC
),但是稍微改变一下结果,这样就不会有太多连续的结果共享相同的结果supplier_id
值。
这一点尤其重要,因为每个供应商的产品往往大致在同一时间进口,因此created_at
相同,这意味着几页结果通常只有一个供应商的产品。
你如何混淆它?
答案 0 :(得分:1)
如果我最终理解你的问题,那么window function row_number()
应该做正确的工作PARTITION
:
SELECT *
FROM (
SELECT *, row_number() OVER (PARTITION BY created_at, supplier_id
ORDER BY created_at DESC) AS rn
FROM products
) a
WHERE rn <= X
ORDER BY created_at DESC
ORDER BY
子句中的OVER
是可选的,但它加快了我在Postgres 9.1测试中的执行速度,因为它与最终的ORDER BY
子句同步。
同时选择同一供应商的最多X
行。如果您需要真正随机选择,则必须在random()
条款中另外按OVER
订购。
除此之外,这不是“随机化”或“重新洗牌”,而是抑制多余的行。如果您希望显示这些行(超过X
),则必须在排序顺序中定义位置。但是,它不可避免地会破坏时间顺序。
答案 1 :(得分:0)
我的理解是,您希望按时间顺序对结果进行排序,但对于created_at
的特定值,只有一个不同的supplier_id
值,而您希望有几个而不是假设它们在排序列表中足够接近。
关键问题是created_at
的分辨率,无论它是什么(timestamp
具有亚秒级分辨率,timestamp(0)
具有一秒的分辨率)都太高了直接用作排序标准。
您可以尝试按时间范围排序。例如:
ORDER BY (extract(epoch from created_at)/3600)::int, RANDOM()
将首先按小时(3600秒)排序插入条目,测量为自1970年1月1日以来经过的小时数,然后使用辅助排序(随机)将结果随机排列在此范围内。如果在同一小时内插入不同供应商的可能性仍然太小,可以使用几个小时或几天。