sqlite如何优化第N个百分位数的查询
Posted
技术标签:
【中文标题】sqlite如何优化第N个百分位数的查询【英文标题】:sqlite how to optimize query for Nth percentile 【发布时间】:2013-12-20 19:03:47 【问题描述】:这是一段代码,它使用sqlite3
python module 从表history
中获取ID 为itemid
的项目的第N 个百分位数value
。
def getNthPercentile(cursor, itemId, N=99.9):
# get 99.9 percentile
# find count of values
cursor.execute("SELECT COUNT(value) FROM history WHERE itemid=?", [itemId])
cnt = int(cursor.fetchone()[0])
# offset gives us teh position of the value in sorted list that represents Nth percentile
offset = int(cnt * (N / 100) - 1)
# sort values
cursor.execute("SELECT value FROM history WHERE itemid = ? ORDER BY value ASC LIMIT 1 OFFSET ?", [itemId, offset])
percentile = float(cursor.fetchone()[0]);
l.debug('itemId=%d, count=%d, offset=%d, %fth percentile=%f' % (itemId, cnt, offset, N, percentile))
# find the (count * pctlVal)th item in sorted values
return percentile
cursor = getDbCursor()
for itemId in listOfItemIds:
print 'Nth percentile for %d is %f' % (itemId, getNthPercentile(cursor, itemId))
问题是:
是否可以在单个查询中执行此操作? 是否可以在单个查询中为 itemId 列表(而不是一次一个)执行此操作?【问题讨论】:
【参考方案1】:我认为在单个查询中是不可能的。 使用 cursor.executescript 在一次执行中调用这两个语句,并将 cnt 作为临时变量存储在 sqlite 中。
cursor.executescript("SELECT COUNT(value) AS itemcount FROM history WHERE itemid=?; \
SELECT value FROM history WHERE itemid = ? ORDER BY value ASC LIMIT 1 OFFSET itemcount * (? / 100) - 1)", \
[itemId, itemId, percentile])
^^ 这个我没测试过,但是应该很接近了。
我不知道是否可以将某种形式的 executescript 与 executemany 结合起来。因此,您可能必须为每个 itemid 在两个 executemanys 或 executescripts 之间做出决定。
【讨论】:
感谢您的努力。在某种程度上,它确实回答了我的问题。不是我希望的,但是......以上是关于sqlite如何优化第N个百分位数的查询的主要内容,如果未能解决你的问题,请参考以下文章
如何在 JavaScript(或 PHP)中获取数组的中位数和四分位数/百分位数?