我想在Postgres中运行一个按预期方式返回结果集的查询(比如说SELECT * FROM products ORDER BY created_at DESC
),但将结果稍微调整一下,这样就不会有太多连续的结果共享supplier_id
值。随机化查询结果共享某个属性
这一点尤其重要,因为每个供应商的产品往往大致同时进口,因此created_at
一样,这意味着几页结果往往只有1个供应商的产品。
你怎么混在一起的?
我想在Postgres中运行一个按预期方式返回结果集的查询(比如说SELECT * FROM products ORDER BY created_at DESC
),但将结果稍微调整一下,这样就不会有太多连续的结果共享supplier_id
值。随机化查询结果共享某个属性
这一点尤其重要,因为每个供应商的产品往往大致同时进口,因此created_at
一样,这意味着几页结果往往只有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
的OVER
子句中的ORDER BY
是可选的,但它在我和Postgres的测试,加快执行9.1,因为它与最终的ORDER BY
条款同步。
最多可以同时从同一供应商处选择X
行。如果您需要真正的随机选择,则必须在OVER
子句中额外订购random()
。
除此之外,这不是“随机化”或“重新洗牌”,而是抑制多余的行。如果要显示这些行(超过X
),则必须按排序顺序定义位置。尽管如此,它将不可避免地破坏时间顺序。
我的理解是要以时间顺序排序结果,但对于created_at
特定的值,只有一个supplier_id
不同的价值,你会希望有一些相反,假设他们在也非常接近排序列表。直接作为排序标准时
的关键问题将是的created_at
分辨率,无论是它(timestamp
具有亚秒级分辨率,timestamp(0)
将有一秒的分辨率)太高。
您可以尝试按照时间范围进行排序。例如:
ORDER BY (extract(epoch from created_at)/3600)::int, RANDOM()
会命令首先由小时(3600秒)插入的条目,如自1/1/70的经过的小时数来测量,然后洗牌内部这一范围的结果与次级排序(随机)。如果在同一个小时内插入不同供应商的可能性仍然很小,则需要几个小时或几天。
你是否希望每个供应商中只有一个出现在这个洗牌数据集中,或者重复供应商都可以,只要他们不是“太频繁”? – 2013-02-12 15:05:52
您是否缩进以**随机**订购 – frictionlesspulley 2013-02-12 15:06:31
重复可以,但不会太频繁。我只是不希望具有相同'supplier_id'的X产品连续出现。 – Avishai 2013-02-12 15:07:39