【发布时间】:2014-02-21 01:02:59
【问题描述】:
好的,所以我在这里有一点学习时间,在弄清楚 A 让它工作的方法之后,我很好奇是否有更多 postgres 经验的人可以帮助我找出一种方法来做到这一点,而无需在场景栏杆后面做很多事情(或对我要获取的每个项目进行一次查询)......现在解释一下:
假设我有 1000 条记录,我们将它们称为“实例”,在具有这些字段的数据库中:
id
user_id
other_id
我想创建一个我可以调用的方法,它会拉入 10 个实例,这些实例都有一个唯一的 other_id 字段,用简单的英语(我意识到这行不通:)):
Select * from instances where user_id = 3 and other_id is unique limit 10
因此,我希望能够在这 10 个实例上运行映射函数并返回类似 [1 ,2,3,4,5,6,7,8,9,10]。
理论上,我目前可能可以做以下两件事之一,尽管我试图避免它们:
存储一个 id 数组并进行单独调用,确保下一个调用显示“不在此数组中”。这里的问题是我正在执行 10 个单独的数据库查询。
提取一大块,比如说 50 个实例,并在 ruby-land 中对它们进行排序以找到 10 个唯一的实例。这不允许我利用数据库中已经完成的任何优化,而且我还会冒着对没有 10 个唯一 other_id 的 50 个项目进行查询的风险,除非我做了另一个查询。
无论如何,希望有人能告诉我我忽略了一个简单的选项 :) 我知道这是在真正需要之前进行某种优化,但是这个函数将会被运行并且一遍又一遍,所以我认为现在这不是浪费时间。
为了记录,我使用的是 Ruby 1.9.3、Rails 3.2.13 和 Postgresql (Heroku)
谢谢!
编辑:只是想举一个在技术上确实有效的函数示例(并且是上面的第 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 个单独的查询:(
【问题讨论】:
-
你可以
GROUP BY other_id,不是吗? -
是的!我正在考虑这个问题,但我不确定您是否可以获得特定数量的组?这是一个问题,而不是陈述:) 我真的不确定是否像这样:“Select * from instances where user_id = 3 group_by other_id limit 10”(可怕的假装语法)会返回按 other_id 分组的 10 个实例,或 10 个组(这就是我想要的)每个都有一个实例。
标签: sql ruby-on-rails ruby arrays postgresql