У меня есть связанный вопрос , но это другая часть МОИ головоломка.
Я хотел бы получить СТАРОЕ ЗНАЧЕНИЕ столбца из строки, которая была ОБНОВЛЕНА - БЕЗ использования триггеров (ни хранимых процедур, ни каких-либо других дополнительных сущностей, не относящихся к SQL / запросам).
У меня есть такой запрос:
UPDATE my_table
SET processing_by = our_id_info -- unique to this worker
WHERE trans_nbr IN (
SELECT trans_nbr
FROM my_table
GROUP BY trans_nbr
HAVING COUNT(trans_nbr) > 1
LIMIT our_limit_to_have_single_process_grab
)
RETURNING row_id;
Если бы я мог выполнить «FOR UPDATE ON my_table» в конце подзапроса, это было бы идеальным (и исправило бы мой другой вопрос / проблему). Но это не сработает: не может быть этого И «GROUP BY» (что необходимо для определения COUNT из trans_nbr). Тогда я мог бы просто взять эти trans_nbr и сначала выполнить запрос, чтобы получить (скоро будут) прежние значения processing_by.
Я пробовал делать что-то вроде:
UPDATE my_table
SET processing_by = our_id_info -- unique to this worker
FROM my_table old_my_table
JOIN (
SELECT trans_nbr
FROM my_table
GROUP BY trans_nbr
HAVING COUNT(trans_nbr) > 1
LIMIT our_limit_to_have_single_process_grab
) sub_my_table
ON old_my_table.trans_nbr = sub_my_table.trans_nbr
WHERE my_table.trans_nbr = sub_my_table.trans_nbr
AND my_table.processing_by = old_my_table.processing_by
RETURNING my_table.row_id, my_table.processing_by, old_my_table.processing_by
Но это не сработало; old_my_table
не отображается вне соединения; предложение RETURNING
не учитывает этого.
Я давно потерял счет всем своим попыткам; Я исследую это буквально часами.
Если бы я мог просто найти надежный способ заблокировать строки в моем подзапросе - и ТОЛЬКО эти строки, и КОГДА происходит подзапрос - все проблемы параллелизма, которых я пытаюсь избежать, исчезли бы ...
ОБНОВЛЕНИЕ: [ВЫТИРАЕТ ЯЙЦО С ЛИЦА] Хорошо, у меня была опечатка в неуниверсальном коде выше, который я написал «не работает»; да ... благодаря Эрвину Брандштеттеру , ниже, который заявил, что будет, я повторил это (после ночного сна, освеженных глаз и банана для завтрака). Поскольку мне потребовалось так много / сложно найти такое решение, возможно, мое затруднение того стоит? По крайней мере, это сейчас на ТАК для потомков ...:>
То, что у меня теперь (это работает), выглядит следующим образом:
UPDATE my_table
SET processing_by = our_id_info -- unique to this worker
FROM my_table AS old_my_table
WHERE trans_nbr IN (
SELECT trans_nbr
FROM my_table
GROUP BY trans_nbr
HAVING COUNT(*) > 1
LIMIT our_limit_to_have_single_process_grab
)
AND my_table.row_id = old_my_table.row_id
RETURNING my_table.row_id, my_table.processing_by, old_my_table.processing_by AS old_processing_by
COUNT (*) соответствует предложению от Flimzy в комментарии к моему другому ( ссылка выше) вопрос. (Я был более конкретен, чем необходимо. [В данном случае.])
Пожалуйста, посмотрите мой другой вопрос для правильной реализации параллелизма и даже неблокирующей версии; ЭТОТ запрос просто показывает, как получить старые и новые значения из обновления, игнорируя плохие / неправильные биты параллелизма.