我正在编写一个程序,必须从数据库中随机选择10个项目。 标准是它的类型应该基于用户的选择。
因此,如果用户选择type 1
,则该计划必须选择10 items
type 1
如果用户选择type 1 and 2
,则该计划必须从5 items
和type 1
5 items
选择type 2
如果用户选择type 1 , 2 and 4
,则该计划必须为3 items
选择each type
,其中一种类型必须有extra item
才能获得10项,哪种类型获得额外的问题必须是随机的。
所以必须为用户可以选择的N种类型进行此操作。
关于如何实现这一目标的任何建议?
顺便说一下,我正在尝试构建一个Random发生器,因此每次结果必须是随机的。
Ps:我在python中编码,但任何语言代码都没问题。
PS:我已经能够使用SQL WHERE子句选择项目了,这不是真正的问题。
问题是,一旦我得到了每个选定类型的项目,我必须选择具有上述比例的10个项目,(即):如果选择4种类型,每种类型2个项目,并且恰好2个额外项目在任何两种类型中。
答案 0 :(得分:3)
一种方法是一次扫描数据库,构建你的十个选择。这是一些伪代码:
if random() < 10.0 / n: ...
i = randrange(10)
在Python中:
result = []
for n, row in enumerate(cursor.execute(user_query), 1):
if n <= 10:
result.append(row)
elif random() < 10.0 / n:
i = randrange(10)
result[i] = row
或者,如果数据库不可查询,并且具有与用户标准匹配的高百分比记录,则可以从整个数据库中随机选择记录,直到找到10个符合条件的唯一记录为止:
result = set()
while len(result) < 10:
record = random.choice(entire_db)
if record not in result and matches(record, user_criteria):
result.add(record)
后一种算法是Python自己的 random.sample()函数使用的两种算法之一。
如果您可以运行查询并且匹配记录的数量可以适合内存,那么整个事情归结为:
random.sample(list(cursor.execute(user_query)), 10)
答案 1 :(得分:1)
基本上你需要把它变成这种形式:
SELECT item
FROM items
WHERE type = ...
ORDER BY RANDOM()
LIMIT 10
见Select random from an SQLite table。 This should work for PostgreSQL too
这很好地让数据库为您完成大部分工作,您需要做的就是弄清楚如何将您的类型作为参数传递,这取决于您的数据库库。
对于多个,我可能只是运行多个查询或动态生成多个联合。
你可以这样做:
SELECT item
FROM items
WHERE type = type1
ORDER BY RANDOM()
LIMIT 5
UNION ALL
SELECT item
FROM items
WHERE type = type2
ORDER BY RANDOM()
LIMIT 5
Python可以像这样生成:
types = ("type1", "type2", "type3")
limit = 10 // len(types) # be careful, for 11 or more types, this will set the limit to 0
sql = """
SELECT item
FROM items
WHERE type = ?
ORDER BY RANDOM()
LIMIT %s
""" % (limit)
unioned_sql = " UNION ALL ".join([sql for i in range(len(types))])
result = cursor.execute(unioned_sql, types)
语法可能有误 - 我暂时没有使用过DB API。它应该提出这个想法。
你提到一个问题是你需要准确选择10个项目,如果比例不能精确到10,那么包括额外项目,所以也许最好将限制硬编码为10(选择最多100项),然后从数据库中获取后修剪列表。
答案 2 :(得分:0)
Return a random element from the non-empty sequence seq.
Return a k length list of unique elements chosen from the population sequence. Used for random sampling without replacement.
用法:
>>> import random
>>> random.choice([1, 2, 3, 4, 5]) # Choose a random element
3
>>> random.sample([1, 2, 3, 4, 5], 3) # Choose 3 elements
[4, 1, 5]
WHERE子句用于仅提取满足a的记录 指定标准。
用法:
SELECT * FROM Items
WHERE Type=1