我在sqlite中有一个名为transactions
的表:
gun | user1
gun | user1
gun | user1
medkit | user1
gun | user2
medkit | user2
等
我只想删除1行gun | user1
所以我提出了一个SQL请求:cursor.execute('DELETE FROM transactions WHERE username =:username AND item_name=:item_name LIMIT 1',{'username':username,'item_name':item_name})
弄清楚我SQLITE ENABLE UPDATE DELETE LIMIT
遇到了问题,我很笨拙地安装它。
经过一番摸索,我发现我可以做这样的事情:
cursor.execute('''DELETE FROM transactions
WHERE username in
(SELECT * FROM transactions WHERE username=:username AND item_name=:item_name LIMIT 1)
''',{'username':username,'item_name':item_name})
但是sql给我一个错误:sub-select returns 2 columns - expected 1
所以我要放弃谷歌搜索,因为我感到困惑。帮助!
完整代码,如果需要:
def remove_item(self, username,item_name):
conn = sqlite3.connect("database.db")
cursor = conn.cursor()
#cursor.execute('DELETE FROM transactions WHERE username =:username AND item_name=:item_name LIMIT 1',{'username':username,'item_name':item_name})
cursor.execute('''DELETE FROM transactions
WHERE username in
(SELECT * FROM transactions WHERE username=:username AND item_name=:item_name LIMIT 1)
''',{'username':username,'item_name':item_name})
conn.commit()
print(f'player.py >> Item {item_name} removed from {username}')
PS:我是SQL和Python的新手,所以...别杀了我:D
答案 0 :(得分:1)
cursor.execute('''DELETE FROM transactions
WHERE username in
(SELECT username FROM transactions WHERE username=:username AND item_name=:item_name LIMIT 1)
''',{'username':username,'item_name':item_name})
将仅从子查询 BUT 中返回一列用户名,然后将其删除具有从子查询中提取的用户名的所有行。
您可以做的是:-
cursor.execute('''DELETE FROM transactions
WHERE rowid =
(SELECT rowid FROM transactions WHERE username=:username AND item_name=:item_name LIMIT 1)
''',{'username':username,'item_name':item_name})
但仅在未使用WITHOUT ROWID子句定义表的情况下。
rowid 是一个特殊的,通常为隐藏的列,它唯一地标识一行,因此提取 rowid 并在WHERE子句中使用它将标识特定行。
请注意,从理论上讲,与item_name和username匹配的任何行都可以删除,而不必删除第一行。确实,您应该使用ORDER BY子句来确保第一行是期望的行。但是,上面的代码很可能会按顺序工作(由于未指定),因此很可能会根据 rowid 来确定,因为这就是所使用的索引。
由于您没有有用的索引,因此可以像使用ORDER一样使用rowid(rowid通常按照插入顺序进行,即第一个插入的rowid为1,然后可能为2和3,依此类推)。因此,更正确的代码可能是:-
cursor.execute('''DELETE FROM transactions
WHERE rowid =
(SELECT rowid FROM transactions WHERE username=:username AND item_name=:item_name ORDER BY rowid LIMIT 1)
''',{'username':username,'item_name':item_name})