SQLite3中如何正确组合使用OR与AND条件查询?
问题原因与解决方法
你的问题出在SQL逻辑运算符的优先级上:AND的优先级高于OR,你原语句会被数据库解析成:
SELECT {x} FROM Stats WHERE (Club =? AND Position =? AND Card =?) OR Card =?
这就导致所有卡牌为ut21 gold non-rare的记录都会被选中,完全跳过了Club和Position的过滤条件,所以返回了大量无关数据。
正确的SQL写法
必须把OR的条件用括号括起来,让它作为一个整体,和前面的AND条件共同生效:
def StatDatabase(self, x, team, position): # Fetches data from the FifaStats database self.cur.execute( "SELECT " + x + " FROM Stats WHERE Club =? AND Position =? AND (Card =? OR Card =?)", (team, position, 'ut21 gold rare', 'ut21 gold non-rare') ) data = self.cur.fetchall() if len(data) > 1: return random.sample(data, 1)[0] elif data: return data[0]
更简洁的写法:用IN代替OR
对于多个等值判断的OR条件,用IN语句可以让代码更简洁,效果完全一致:
self.cur.execute( "SELECT " + x + " FROM Stats WHERE Club =? AND Position =? AND Card IN (?, ?)", (team, position, 'ut21 gold rare', 'ut21 gold non-rare') )
额外优化建议
- 去掉不必要的字符串格式化:代码里的
f'{team}'、f'{position}'完全多余,直接传入变量即可,参数化查询会自动处理类型转换。 - 简化返回逻辑:不需要循环遍历结果,直接通过索引取值就行,比如
random.sample(data,1)[0]可以直接拿到随机选中的元素,data[0]拿到唯一结果。 - 防范SQL注入风险:你直接拼接字段名
x的做法有风险,如果x是用户可控的输入,可能被注入恶意SQL。建议先验证字段名是否在允许的列表内:
# 提前定义允许查询的字段 ALLOWED_FIELDS = ['Overall', 'Potential', 'Name', 'Position'] if x not in ALLOWED_FIELDS: raise ValueError("不允许查询的字段")
内容的提问来源于stack exchange,提问作者Kelan Westwood
相关产品推荐
相关产品推荐

