#mysql #sql #sqlite #doctrine-orm
#mysql #sql #sqlite #doctrine-orm
Вопрос:
У меня есть хороший запрос, который обновляет «родительское» (наблюдение) значение в зависимости от того, что задано в таблице «дочернее» (действие). Наблюдение может иметь много действий, и когда все они помечены как «разрешенные», родительское наблюдение тоже помечается как разрешенное.
Это скрипт MySQL.
UPDATE observation
INNER JOIN
(
SELECT
co.id AS obs_id,
SUM(at.resolved) AS tasks_resolved,
COUNT(at.id) as total_tasks
FROM observation co
INNER JOIN action_task at ON at.observation_id = co.id
WHERE co.id = (
SELECT task.observation_id FROM action_task task
WHERE task.id = 5
)
) val ON val.obs_id = observation.id
SET observation.resolved = CASE
WHEN val.tasks_resolved=val.total_tasks THEN 1
ELSE 0
END
;
Я хотел перенести этот запрос в репозиторий Doctrine 2. В течение дня я пытался создать для него скрипт построения запросов, но в итоге запустил весь скрипт из EXEC
команды.
Я начал создавать функциональные тесты, но он выдал ошибку, потому что у меня не может быть ВНУТРЕННЕГО СОЕДИНЕНИЯ в an UPDATE
— Это потому, что ВНУТРЕННЕЕ СОЕДИНЕНИЕ разрешено только в MySQL.
Поэтому я обновил запрос, чтобы удалить ВНУТРЕННЕЕ СОЕДИНЕНИЕ в UPDATE
. Это выглядит примерно так:
UPDATE observation, (
SELECT
SUM(at.resolved) AS tasks_resolved,
COUNT(at.id) as total_tasks
FROM observation co
INNER JOIN action_task at ON at.observation_id = co.id
WHERE co.id = (
SELECT task.observation_id FROM action_task task
WHERE task.id = 5
)
) val
SET observation.resolved = CASE
WHEN val.tasks_resolved=val.total_tasks THEN 1
ELSE 0
END
WHERE observation.id = (
SELECT task.observation_id FROM action_task task
WHERE task.id = 5
)
;
Теперь я столкнулся с проблемой, когда SQL работает нормально, когда он используется на сайте, но он терпит неудачу, когда я пытаюсь запустить функциональные тесты. Это выдает ошибку:
PDOException: SQLSTATE[HY000]: General error: 1 near ",": syntax error
Обычный сайт работает на MySQL, а функциональные тесты выполняются с использованием SQLite. Я думаю, что это сэкономило бы больше времени на сборке запроса с помощью Query Builder и избавило бы от проблем с кросс-базой данных.
Мне интересно, есть ли способ написать запрос с помощью Query Builder?
Ответ №1:
Эта запятая по-прежнему является оператором соединения (или была бы, если бы она была разрешена в ОБНОВЛЕНИИ).
Сам оператор UPDATE допускает только одну таблицу. Вы должны выполнять поиск с помощью коррелированных подзапросов:
UPDATE observation
SET resolved = (SELECT SUM(resolved) = COUNT(id)
FROM action_task
WHERE observation_id = observation.id)
WHERE id = (SELECT observation_id
FROM action_task
WHERE id = 5)