我正在尝试使用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']
谢谢!
答案 0 :(得分:2)
SQLITE中没有somehow_create_an_instance_of
功能
给我同样的错误,需要使用更复杂的查询或函数来创建
Here is a list of unsupported analytical functions在SQLITE
中不可用NTILE就是其中之一
优化器首先进入查询内部以查找NTILE () OVER
,它认为这是一个列名,不期望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)
声明发挥作用的地方。如果学生的百分位数超过50%,则他们属于排名第50的百分位数。其他人都属于#2组。
答案 1 :(得分:1)
Window functions 自版本 3.25.0 (2018-09-15) 起在 SQLite 中受支持。 ntile(N)
是支持的窗口函数之一:
参数 N 作为整数处理。此函数将分区尽可能均匀地划分为 N 个组,并按照 ORDER BY 子句定义的顺序或以其他任意顺序为每个组分配一个介于 1 和 N 之间的整数。如有必要,首先出现更大的群体。此函数返回分配给当前行所属组的整数值。
您可以通过以下方式测试与您的 Python 链接的 libsqlite3
版本:
python -c "import sqlite3; print(sqlite3.sqlite_version)"
例如:
Ubuntu Xenial
$ docker run --rm -it ubuntu:xenial
# apt update
# apt install -y python3
# python3 -c "import sqlite3; print(sqlite3.sqlite_version)"
3.11.0
Debian Buster 上的官方 Python Docker 映像
$ docker run --rm -it python:3.6-buster \
python3 -c 'import sqlite3; print(sqlite3.sqlite_version)'
3.27.2
并且您的查询在具有窗口函数支持的 SQLite 版本上运行良好:
>>> import sqlite3
>>> import pandas
>>>
>>> conn = sqlite3.connect(':memory:')
>>> marks = pandas.DataFrame({
... 'StudentID': ['S1', 'S2', 'S3', 'S4', 'S5'],
... 'Marks': [75, 83, 91, 83, 93]
... })
>>> marks.to_sql('marks_sql', conn, if_exists='replace')
>>>
>>> sql = '''
... SELECT StudentID, Marks, NTILE(2) OVER (ORDER BY Marks DESC) g
... FROM marks_sql
... '''
>>> pandas.read_sql_query(sql, conn)
StudentID Marks g
0 S5 93 1
1 S3 91 1
2 S2 83 1
3 S4 83 2
4 S1 75 2