обновить со многими распространенными подвыражениями - PullRequest
0 голосов
/ 22 февраля 2019

Каков наилучший способ расчета таблицы, в которой многие столбцы рассчитываются на основе других столбцов в той же таблице, а формулы сложным образом строятся друг на друга.

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

update x set b1 = a1 + a2;
update x set b2 = a3 * b1;
update x set b3 = a4 * b2;
...

Или вы можете сделать все в одном обновлении, если развернуть формулы вручную:

update x set
  b1 = a1 + a2,
  b2 = a3 * (a1 + a2),
  b3 = a4 * (a3 * (a1 + a2));

Проблема здесьчто эти формулы могут стать огромными и их трудно изменить и отладить.

Есть ли какой-нибудь способ в Postgres (или, возможно, даже в SQL) в целом, чтобы вы могли иметь как производительность, так и удобство сопровождения в этих случаях?

Вот что я хотел бы сделать:

update x set
  b1 = _b1,
  b2 = _b2,
  b3 = _b3
with
  _b1 = a1 + a2,
  _b2 = a3 * _b1,
  _b3 = a4 * _b2;

У меня есть одно рабочее решение, где формулы определены в функции с несколькими возвращаемыми значениями, но это довольно негибко в некоторых других отношениях, поэтому яищу альтернативы.

Ответы [ 2 ]

0 голосов
/ 11 апреля 2019

Я придумал что-то близкое к тому, что искал:

update x set (b1, b2, b3) = ((
  select b1, b2, b3
  from (select b1, b2, a4 * b2 as b3
  from (select b1, a3 * b1 as b2
  from (select a1 + a2 as b1
  ) as _) as _) as _
));

Это все еще более многословно, чем мне бы хотелось, но в основном достигает цели не необходимости расширять формулы без использованияфункция.

0 голосов
/ 22 февраля 2019

В последних версиях PostgreSQL вы можете использовать следующее:

UPDATE atable
SET (col1, col2, col3) =
SELECT expr1, expr2, expr3
FROM ...

Если вам нужно повторно использовать вычисленные выражения в запросе, вы можете использовать WITH:

WITH t1(x1) AS (
   SELECT /* complicated */
), t2(x2) AS (
   SELECT /* complicated using t1 */
) ...
SELECT /* final results */

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

...