SQLite - 用可变数量的条件过滤结果

0 投票
1 回答
1504 浏览
提问于 2025-04-17 22:25

我最近在玩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

撰写回答