Создание одного запроса с подзапросом, по сути, запрос на вставку с запросом на выборку

Я создал функцию входа в систему с помощью flask, она состоит из кода, который открывает соединение с базой данных, а затем выбирает имя пользователя на основе введенного имени пользователя. Если быть точнее, вот запрос:

cursor.execute("""
SELECT username FROM user_tbl 
WHERE username = %s""",
(self.username))

После этого я проверяю длину извлеченных данных, если длина равна 0, я открываю другое соединение, а затем выполняю запрос на вставку, например:

cursor.execute("""
INSERT INTO 
user_tbl(username,password,email,user_type) 
VALUES(%s,%s,%s,%s)""", 
(self.username,self.password,self.email,self.user_type))

Я выполнял этот процесс с момента написания кода с помощью PHP и хотел бы подтвердить, есть ли способ объединить эти два запроса. Я исследовал как сумасшедший и, кажется, не могу найти ответ ... или, по крайней мере, ответы, которые работают.

Прямой INSERT INTO в MySQL с предложением WHERE, основываясь на принятом ответе, INSERT INTO...SELECT - это путь, однако после изучения его в основном речь идет о передаче данных из другой таблицы в другую, я ориентируюсь на одну таблицу (извиняюсь, если я что-то упустил).

Я не могу найти ссылку, однако я нашел другой ответ, в котором упоминалось, что единственный раз, когда вы увидите предложение WHERE в запросе INSERT (помимо ответа, который я разместил выше), это когда вы проверяете, нет ли ничего 'EXISTS' (что имеет смысл, и на основе этого ответа я сделал вывод, что наличие предложения where в запросе на вставку — это нормально).

После проверки подзапроса к предложению WHERE и следующих примеров по этой ссылке: https://www.essentialsql.com/get-ready-to-learn-sql-server-21-using-subqueries-in-the-where-clause/ я создал свой собственный запрос:

INSERT INTO user_tbl(username,password,email,user_type)
VALUES("test.test","test","test","test")
WHERE username IN 
(SELECT username FROM user_tbl WHERE username = "test.test");

Причина, по которой я выбрал IN, заключается в том, что, как указано в ссылке, как только подзапрос возвращает NULL, IN возвращает false для предложения WHERE (по крайней мере, так я это интерпретировал).

К сожалению, каждый раз, когда я запускаю этот код на своем терминале, я получаю эту синтаксическую ошибку:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE username IN (SELECT username FROM user_tbl WHERE username = "test.test")'

Отсюда и заголовок: «Можете ли вы, ребята, объяснить, в чем именно мой код синтаксически неверен?» Кроме того, не могли бы вы указать мне правильное направление, так как я очень потерялся в этом.

Заранее спасибо,

Инно

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
308
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

вы не можете использовать ту же таблицу, но вы можете «скрыть» SELECT, тогда MySQL не увидит этого:

INSERT INTO user_tbl(username,password,email,user_type)
VALUES("test.test","test","test","test")
WHERE username IN 
(SELECT * FROM ( 
   SELECT username FROM user_tbl WHERE username = "test.test" 
   ) as myuser
);  
Ответ принят как подходящий

Я понимаю, что вы хотите INSERT новую запись в user_tbl только в том случае, если ее еще нет.

MysQL имеет для этого специальный синтаксис, который называется ВСТАВЬТЕ... ПРИ ОБНОВЛЕНИИ ДУБЛИКАЦИОННОГО КЛЮЧА.

Чтобы это работало, вам нужно, чтобы столбец username был первичным ключом в вашей таблице (или имел ограничение UNIQUE).

Тогда вы можете просто сделать:

cursor.execute(
    """
        INSERT INTO user_tbl(username,password,email,user_type) 
        VALUES(%s,%s,%s,%s)
        ON DUPLICATE KEY UPDATE username = VALUES(username)
    """, 
    (self.username,self.password,self.email,self.user_type)
)

Если для данного username записи уже не существует, создается новая запись. В противном случае вызывается предложение UPDATE (здесь это просто переназначит то же значение username , что в основном не работает).

Необходимо ли ограничение Unique? Я планирую убедиться, что имена пользователей в любом случае останутся уникальными, однако, если это необходимо, я просто изменю столбец

Inno Ramos 07.04.2019 17:16

Да, username должен быть либо первичным ключом таблицы, либо иметь ограничение UNIQUE. Так или иначе, это указывает MySQL на то, что данный столбец должен быть уникальным, и позволяет реализовать функциональность ON DUPLICATE KEY.

GMB 07.04.2019 17:21

Привет еще раз, возможно ли, чтобы запрос возвращал false для дублирующего ключа?

Inno Ramos 08.04.2019 03:24

Другие вопросы по теме