Повторно использовать результат сложного запроса в других запросах без повторного выполнения сложного запроса. - PullRequest
0 голосов
/ 27 ноября 2011

У меня сложный запрос в PostgreSQL, и я хочу использовать его результат в других операциях, таких как ОБНОВЛЕНИЯ и УДАЛЕНИЯ, что-то вроде:

<COMPLEX QUERY>;
UPDATE WHERE <COMPLEX QUERY RESULT> = ?;
DELETE WHERE <COMPLEX QUERY RESULT> = ?;
UPDATE WHERE <COMPLEX QUERY RESULT> = ?;

Я не хочу выполнять сложныйзапросить один раз для каждой операции.Один из способов избежать этого - сохранить результат в таблице и использовать его для WHERE и JOINS, а после окончания отбросить временную таблицу.

Я хочу знать, есть ли другой способ без сохранения результатов в базе данных, но уже используя результаты в памяти.

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

Ответы [ 2 ]

2 голосов
/ 27 ноября 2011

Вы можете просмотреть результаты запроса, как показано в @phatfingers (возможно, с общей record или скалярной переменной вместо rowtype, если тип результата запроса не соответствует ни одному из существующих типов строк).Это хорошая идея для нескольких результирующих строк или когда необходима последовательная обработка .

Для больших наборов результатов ваш исходный подход будет работать быстреена порядок.Гораздо дешевле сделать массовую INSERT / UPDATE / DELETE с помощью одной команды SQL, чем писать / удалять постепенно, по одной строке за раз.

A временная таблица - это то, что нужноповторное использование таких результатов.Он сбрасывается автоматически в конце сеанса.Вам нужно только явно удалить, если вы хотите избавиться от него сразу или в конце транзакции.Я цитирую руководство здесь :

Временные таблицы автоматически удаляются в конце сеанса или, возможно, в конце текущей транзакции.

Для больших временных таблиц было бы неплохо запустить ANALYZE после их заполнения.

Записываемый CTE

Вот демонстрация того, что Павел добавил в своем комментарии:

CREATE TEMP TABLE t1(id serial, txt text);
INSERT INTO t1(txt)
VALUES ('foo'), ('bar'), ('baz'), ('bax');

CREATE TEMP TABLE t2(id serial, txt text);
INSERT INTO t2(txt)
VALUES ('foo2'),('bar2'),('baz2');

CREATE TEMP TABLE t3 (id serial, txt text);

WITH x AS (
    UPDATE t1
    SET    txt = txt || '2'
    WHERE  txt ~~ 'ba%'
    RETURNING txt
    )
, y AS (
    DELETE FROM t2
    USING  x
    WHERE  t2.txt = x.txt
    RETURNING *
    )
INSERT INTO t3
SELECT *
FROM   y
RETURNING *;

Подробнее см. В главе Операции изменения данных в WITH в руководстве.

1 голос
/ 27 ноября 2011
DECLARE
    r foo%rowtype;
BEGIN
    FOR r IN [COMPLEX QUERY]
    LOOP
    -- process r
    END LOOP;
    RETURN;
END
...