Рассмотрим следующие таблицы:
CREATE TABLE ex1(
id serial,
property text,
matched boolean DEFAULT false
);
INSERT INTO ex1(property) VALUES
('red'), ('green'), ('blue'), ('yellow'), ('cyan'), ('magenta')
;
CREATE TABLE ex2(
id serial,
property text,
matched boolean DEFAULT false
);
INSERT INTO ex2(property) VALUES
('orange'), ('purple'), ('green'), ('red'), ('blue'), ('yellow'), ('white'), ('black')
;
Следующий запрос должен обновить столбец matched
обеих таблиц для общих строк (это минимальный пример; на практике существует гораздо больше столбцов в играть и еще много критериев). Это также, что важно, возвращает id
s строк, которые были обновлены, в каждой таблице. Позже мне понадобится эта информация для аналитики:
WITH tmp AS (
UPDATE ex1 L
SET matched = true
FROM ex2 R
WHERE L.property = R.property
AND L.matched = false
AND R.matched = false
RETURNING L.id AS leftid, R.id AS rightid
)
UPDATE ex2
SET matched = true
FROM tmp
WHERE tmp.rightid = ex2.id
RETURNING tmp.leftid, tmp.rightid;
Как и ожидалось, это выдает
leftid | rightid
-------|--------
2 | 3
1 | 4
3 | 5
4 | 6
и соответствующим образом обновляет столбец matched
, только для тех строк, идентификаторы которых находятся в этом таблица.
Теперь, если бы мне нужно было выполнить один и тот же запрос дважды для одной и той же таблицы, я бы ожидал, что обе все строки будут изменены на matched = true
и будут возвращены в обеих столбцы leftid
и rightid
. Вместо этого:
WITH tmp AS (
UPDATE ex1 L
SET matched = true
FROM ex1 R
WHERE L.property = R.property
AND L.matched = false
AND R.matched = false
RETURNING L.id AS leftid, R.id AS rightid
)
UPDATE ex1
SET matched = true
FROM tmp
WHERE tmp.rightid = ex1.id
RETURNING tmp.leftid, tmp.rightid;
возвращает пустую таблицу, несмотря на обновление таблицы ex1
. Используя pgAdmin, я вижу, что оператор UPDATE в объявлении таблицы tmp
выполняется нормально и возвращает правильную информацию. Кроме того, когда я делаю эти две вещи в отдельных шагах (создаю фактическую таблицу из tmp
, а не просто временную таблицу, используя with
), она работает как ожидалось.
Почему этот запрос ничего не возвращает, когда я использую одну и ту же таблицу с обеих сторон? И как мне это исправить?