使用唯一字段返回postgresql查询中的前X个记录

好的,所以我在这里有一点学习的时刻,在找到一种让它发挥作用方法之后,我很好奇是否有任何有更多postgres经验的人可以帮我找到一种方法来做到这一点而不做一个在场景背后的整个lotta rails(或者我正在尝试获得的每个项目进行单一查询)…现在进行解释:

假设我有1000条记录,我们称之为“实例”,在具有以下字段的数据库中:

id user_id other_id 

我想创建一个我可以调用的方法,它引入10个实例,这些实例都有一个唯一的other_id字段,用简单的英语(我意识到这不起作用:)):

 Select * from instances where user_id = 3 and other_id is unique limit 10 

因此,不是拉入一个10个实例的数组,其中user_id是3,你可以得到多个实例,其中other_id是5,我希望能够在这10个实例上运行一个map函数并返回类似[1,2, 3,4,5,6,7,8,9,10。

理论上,我现在可能会做两件事之一,虽然我试图避免它们:

  1. 存储一组id并进行单独调用,确保下一个调用“不在此数组中”。 这里的问题是我正在做10个单独的数据库查询。

  2. 拉入大量的50个实例并在ruby中分类,找到10个独特的实例。 这不允许我利用已经在数据库中完成的任何优化,并且我还冒着查询50个没有10个唯一的other_id的项目的风险,除非我,否则我会被困在那些做了另一个问题。

无论如何,希望有人能够告诉我,我忽略了一个简单的选择:)我知道这是一种优化之前它真的需要但是这个function将会一遍又一遍地运行所以我认为它不是一个现在浪费时间。

为了记录,我使用Ruby 1.9.3,Rails 3.2.13和Postgresql(Heroku)

谢谢!

编辑 :只是想给出一个技术上有效的function的例子(上面的数字1)

 def getInstances(limit, user) out_of_instances = false available = [] other_ids = [-1] # added -1 to avoid submitting a NULL query until other_ids.length == limit || out_of_instances == true instance = Instance.where("user_id IS ? AND other_id  ALL (ARRAY[?])", user.id, other_ids).limit(1) if instance != [] available << instance.first other_ids << instance.first.other_id else out_of_instances = true end end end 

你会运行:

 getInstances(10, current_user) 

虽然这有效,但它并不理想,因为它每次被调用时都会导致10个单独的查询:(

在单个SQL查询中,可以使用SELECT DISTINCT ON...轻松实现SELECT DISTINCT ON...这是PostgreSQL特有的function。

请参阅http://www.postgresql.org/docs/current/static/sql-select.html

SELECT DISTINCT ON(expression [,…])仅保留给定表达式求值的每组行的第一行。 使用与ORDER BY相同的规则解释DISTINCT ON表达式(参见上文)。 请注意,每个集合的“第一行”是不可预测的,除非使用ORDER BY来确保首先出现所需的行

用你的例子:

  SELECT DISTINCT ON (other_id) * FROM instances WHERE user_id = 3 ORDER BY other_id LIMIT 10