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)中获取数组的中位数和四分位数/百分位数?

如何从 PHP 中的双精度数组中计算第 n 个百分位数?

postgresql中的第n个百分位数计算

通过查询计算 SQLiteDB 的下四分位数和上四分位数

如何计算列的每个值所在的百分位数? (Spark SQL)[重复]

大熊猫是否表现出错误的百分位数?