SQLite - 用可变数量的条件过滤结果
我最近在玩Python和SQLite,刚开始学习这两个东西。我想为一些文件创建一个标签数据库,并且希望能通过AND/OR操作来过滤这些标签。简单的解决方案是:
taglist = ['tag1', 'tag2']
rows = c.execute("SELECT DISTINCT * FROM tags WHERE tag=? OR tag=?", [taglist[0], taglist[1]])
for row in rows:
#do stuff
不过问题是,这样做限制了我在SQL查询中可以使用的AND/OR条件数量(在这个例子中是两个)。我该如何输入一个可变数量的条件,让用户可以随意使用AND/OR来组合多个标签呢?
编辑:我已经拼凑出了一些东西,但看起来不是很优雅。我搞不清楚怎么把“taglist”这个列表放进SQL查询里。它需要的是一个字符串,而不是列表,即使把列表转换成字符串也似乎不行。最后我只能把它拼接到SQL查询字符串里。
这是我想到的一个方法,可以把多个标签用AND连接起来。它首先执行一个OR子查询,获取所有有匹配标签的id,然后再进行COUNT,筛选出那些出现次数和查询标签数量相同的id。如果某个id出现的次数少于这个数量,那说明它没有包含标签列表中的所有标签。
taglist = ('tag1','tag2')
tagstring = str(taglist)
tagcount = len(taglist)
rows = c.execute("SELECT id FROM (SELECT * FROM tags WHERE tag IN " + tagstring + ") GROUP BY id HAVING COUNT(id)=(?)", [tagcount])
这个方法似乎有效,但我总觉得还有更好的办法。
1 个回答
0
我不太懂Python,不过在SQL方面,你可以看看IN子句。
你需要再确认一下Python的部分,这是我通过快速搜索语法得到的信息。(对于SQL语句构建的语法,我只是用了你代码里的内容,可能还有更简洁的方法可以做到)。
taglist = ['tag1', 'tag2']
s = ""
for i in range(len(taglist)):
s+=str(taglist[i])
rows = c.execute("SELECT DISTINCT * FROM tags WHERE tag IN ( ? )", [s])
for row in rows:
#do stuff