如何在sqlite中删除1行乘2变量?

时间:2019-06-06 03:06:38

标签: python sqlite

我在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

1 个答案:

答案 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})