Я пытаюсь обновить некоторые записи с помощью этого запроса, который, по сути, является просто способом установить «состояние» для клиента с учетом его «дней с момента последнего заказа»:
UPDATE customers AS c1
INNER JOIN (
SELECT id, DATEDIFF(NOW(), agg.cdt) AS acdt
FROM customers
INNER JOIN
(
SELECT c.id AS cid, max(o.datetime) as cdt
FROM customers AS c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.state = 20
GROUP BY c.id
) AS agg ON customers.id = agg.cid
WHERE account_type IN (1, 2)
AND deleted = 0
AND (account_management_state IN (0, 1, 2) OR account_management_state IS NULL)
) AS c2 ON c1.id = c2.id
SET c1.account_management_state = CASE
WHEN c2.acdt <= 90 THEN 0
WHEN c2.acdt >= 91 AND c2.acdt <= 360 THEN 1
WHEN c2.acdt > 360 OR c2.acdt IS NULL THEN 2
END
WHERE c1.id = c2.id;
Но я ' m получение:
Код ошибки: 1175. Вы используете режим безопасного обновления и пытались обновить таблицу без WHERE, в которой используется столбец KEY. Чтобы отключить безопасный режим, переключите параметр в настройках -> SQL Редактор и переподключение.
Я использую ключ таблицы в финальном WHERE
, c1.id
- это ключ таблицы customers
. Использование SET SQL_SAFE_UPDATES = 0;
не вариант. Я также пробовал использовать WHERE c1.id > 0
, но безрезультатно.
Обратите внимание, что я попытался запустить запрос вручную, изменив SET SQL_SAFE_UPDATES = 0;
, запрос работает, как ожидалось, но это должен быть автоматический c процесс.
Итак, мои варианты:
- Используя один запрос,
SQL_SAFE_UPDATES
нельзя использовать. - Используя Python курсоры,
SQL_SAFE_UPDATES
можно использоваться. (см. БОКОВОЕ ПРИМЕЧАНИЕ ) - [вставьте здесь параметр]
- (я не хочу этого делать) Итерировать по каждой записи (используя Python ORM ) и обновите запись. Это глупо и займет вечность.
ОБНОВЛЕНИЕ
Также пробовали:
Использование того же идентификатора
UPDATE
...
WHERE c1.id = c1.id ;
Добавление огромного лимита после каждого подзапроса (как предлагает @Akina):
UPDATE customers AS c1
INNER JOIN (
SELECT id, DATEDIFF(NOW(), agg.cdt) AS acdt
FROM customers
INNER JOIN
(
SELECT c.id AS cid, max(o.datetime) as cdt
FROM customers AS c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.state = 20
GROUP BY c.id
LIMIT 100000000
) AS agg ON customers.id = agg.cid
WHERE account_type IN (1, 2)
AND deleted = 0
AND (account_management_state IN (0, 1, 2) OR account_management_state IS NULL)
LIMIT 100000000
) AS c2 ON c1.id = c2.id
SET c1.account_management_state = CASE
WHEN c2.acdt <= 90 THEN 0
WHEN c2.acdt >= 91 AND c2.acdt <= 360 THEN 1
WHEN c2.acdt > 360 OR c2.acdt IS NULL THEN 2
END
WHERE c1.id = c2.id;
Комбинация обоих идентификаторов:
UPDATE
...
WHERE c1.id > 0 and c2.id > 0;
Ни один из них не работает. По-прежнему получаю Error Code: 1175
.
СТОРОННЕЕ ПРИМЕЧАНИЕ
Это часть процесса Python / Flask с использованием клиента MySQL python и курсоров. Я могу использовать SQL_SAFE_UPDATES
, если это делается с помощью курсора Python. Это не работает:
Использование разных запросов (не выдаёт ошибку, просто ничего не обновляет):
connection = db.get_conn()
cursor = connection.cursor()
cursor.execute('SET SQL_SAFE_UPDATES = 0;')
cursor.execute(query) # from the original query
cursor.execute('SET SQL_SAFE_UPDATES = 1;')
Используя один запрос (не выдает ошибку, он просто ничего не обновляет):
connection = db.get_conn()
cursor = connection.cursor()
cursor.execute('''
SET SQL_SAFE_UPDATES = 0;
UPDATE ...;
SET SQL_SAFE_UPDATES = 1;
''')
Используя BEGIN .. END
(думал, что увидел свет, но нет), получаем а ProgrammingError
:
connection = db.get_conn()
cursor = connection.cursor()
cursor.execute('''
BEGIN
SET SQL_SAFE_UPDATES = 0;
UPDATE ...;
SET SQL_SAFE_UPDATES = 1;
END
''')