You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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')
)

额外优化建议

  1. 去掉不必要的字符串格式化:代码里的f'{team}'、f'{position}'完全多余,直接传入变量即可,参数化查询会自动处理类型转换。
  2. 简化返回逻辑:不需要循环遍历结果,直接通过索引取值就行,比如random.sample(data,1)[0]可以直接拿到随机选中的元素,data[0]拿到唯一结果。
  3. 防范SQL注入风险:你直接拼接字段名x的做法有风险,如果x是用户可控的输入,可能被注入恶意SQL。建议先验证字段名是否在允许的列表内:
# 提前定义允许查询的字段
ALLOWED_FIELDS = ['Overall', 'Potential', 'Name', 'Position']
if x not in ALLOWED_FIELDS:
    raise ValueError("不允许查询的字段")

内容的提问来源于stack exchange,提问作者Kelan Westwood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 11:18:28