我正在尝试使用 NTILE 函数从 Pandas 查询 SQLite 数据库,但我没有成功,即使我已经多次重新检查语法。

下面的独立示例。
设置:

import pandas as pd
from sqlalchemy import create_engine
disk_engine = create_engine('sqlite:///test.db')

marks = pd.DataFrame({'StudentID': ['S1', 'S2', 'S3', 'S4', 'S5'],
                      'Marks': [75, 83, 91, 83, 93]})
marks.to_sql('marks_sql', disk_engine, if_exists='replace')

现在尝试使用 NTILE:
q = """select StudentID, Marks, NTILE(2) OVER (ORDER BY Marks DESC)
        AS groupexample FROM marks_sql"""
pd.read_sql_query(q, disk_engine)

回溯很长,但它的主要部分是:
OperationalError: near "(": syntax error
OperationalError: (sqlite3.OperationalError) near "(": syntax error [SQL: 'select StudentID, Marks, NTILE(2) OVER (ORDER BY Marks DESC)\n        AS groupexample FROM marks_sql']

谢谢!

最佳答案

SQLITE 中没有 NTILE () OVER 功能

给我同样的错误,需要使用更复杂的查询或函数来创建它

Here is a list of unsupported analytical functions 在 SQLITE 中不可用

NTILE 就是其中之一

优化器首先进入查询以查找 OVER ,它认为它是一个列名,并且不希望 ( 跟随一个列名,所以给你这个错误。

要复制 NTILE 试试这个:

select * ,
case
  when
    (select count(*)+0.0 from marks_sql b where table.Marks >= b.Marks)
    /(select count(*) from marks_sql ) >0.5
  then 1
  else 2 end
from marks_sql;

为了以这样一种方式做到这一点,即表格可以增长并且这种技术仍然适用,我们做了一些事情:

所以首先我们通过 Marks 对表进行排序(本质上是创建一个排名)。这会计算具有更高或等于 Marks 的行:
select count(*)+0.0 from marks_sql b where table.Marks >= b.Marks  --rank of Mark

我们添加 0.0 使这个数字成为浮点数,以便我们的分数在下一步中起作用。

然后我们将排名除以总行数
select count(*) from marks_sql -- row count

这为我们提供了分数范围的分布,每个学生的百分位数。但是我们不关心每个确切的百分位数,我们关心 NTILE(2) 或者它们是否在上半部分。

这就是 CASE 语句发挥作用的地方。如果学生的百分位数超过 50%,他们就属于 #1 组,即前 50 个百分位数。其他所有人都属于#2 组。

关于python - 来自 Pandas 的 Sqlite 的 NTILE 给出了操作错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37579374/

10-12 16:54