Как удалить 1 строку по 2 переменным в sqlite? - PullRequest
1 голос
/ 06 июня 2019

У меня есть таблица с именем transactions в sqlite:

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, который я тупой, чтобы установить.

После некоторого поиска в Google я понял, что я могу что-то сделатьвот так:

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

, поэтому я отказываюсь от поиска в Google, потому что я в замешательстве.help!


полный код, если необходимо:

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 Ответ

1 голос
/ 06 июня 2019
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})

вернет только один столбец имя пользователя из подзапроса НО , который затем удалит все строки, имеющие извлеченное имя пользователя из подзапроса.

Что вы можете сделать: -

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 , поскольку это будет используемый индекс.

Поскольку у вас нет полезного индекса, выможет использовать rowid как для ORDER (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})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...