PostgreSQL: использование вычисляемого столбца в том же запросе - PullRequest
39 голосов
/ 12 января 2012

У меня проблемы с использованием вычисляемого столбца в postgres.Аналогичный код, который работает в SQL, приведен ниже. Возможно ли воссоздать его в PostgreSQL?

select cost_1, quantity_1, cost_2, quantity_2, 
      (cost_1 * quantity_1) as total_1,
      (cost_2 * quantity_2) as total_2,
      (calculated total_1 + calculated total_2) as total_3
from data;

В PostgreSQL аналогичный код возвращает ошибку, которая:

столбец total_1 и total_2 не существует.

Ответы [ 5 ]

43 голосов
/ 13 января 2012

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

select cost1,
       quantity_1,
       cost_2,
       quantity_2
       total_1 + total_2 as total_3
from (
    select cost_1, 
           quantity_1, 
           cost_2, 
           quantity_2, 
           (cost_1 * quantity_1) as total_1,
           (cost_2 * quantity_2) as total_2
    from data
) t

Не будет никакого снижения производительности на этом.

действительно удивлен, что ваш исходный оператор SQL вообще выполняется в СУБД)

27 голосов
/ 10 апреля 2016

Если вам не нравится перенос всего запроса с внешним запросом, вы можете использовать LATERAL для вычисления промежуточного total_1 и total_2:

SELECT cost_1, quantity_1, cost_2, quantity_2, total_1, total_2,
       total_1 + total_2 AS total_3
FROM data
,LATERAL(SELECT cost_1 * quantity_1, cost_2 * quantity_2) AS s1(total_1,total_2);

DBFiddle Demo

Вывод:

╔═════════╦═════════════╦═════════╦═════════════╦══════════╦══════════╦═════════╗
║ cost_1  ║ quantity_1  ║ cost_2  ║ quantity_2  ║ total_1  ║ total_2  ║ total_3 ║
╠═════════╬═════════════╬═════════╬═════════════╬══════════╬══════════╬═════════╣
║      1  ║          2  ║      3  ║          4  ║       2  ║      12  ║      14 ║
║      3  ║          5  ║      7  ║          9  ║      15  ║      63  ║      78 ║
║     10  ║          5  ║     20  ║          2  ║      50  ║      40  ║      90 ║
╚═════════╩═════════════╩═════════╩═════════════╩══════════╩══════════╩═════════╝
11 голосов
/ 10 марта 2017

Как правило, есть две вещи, которые вам нужно знать о предложении SELECT:

  • Хотя оно написано first , оно оценивается last, за исключением пункта ORDER BY.Вот почему вы не можете использовать любые вычисляемые поля или псевдонимы в любом другом предложении (в частности, в предложении WHERE) , за исключением в предложении ORDER BY.
  • Вычисления в предложении SELECTвыполняются в параллельно или, по крайней мере, обрабатываются так, как если бы они были.Вот почему вы не можете использовать один расчет как часть другого.

Итак, краткий ответ: вы не можете, и это по замыслу.

Заметное исключение дляэто Microsoft Access, где вы действительно можете использовать вычисления в последующих столбцах и предложениях WHERE.Однако, хотя это удобно, на самом деле это не является преимуществом: невыполнение вышеуказанных принципов менее эффективно.Но это нормально для баз данных с малой нагрузкой, для которых предполагается использовать Access.

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

Редактировать

Не изменив точку исходного ответа, я подумал, что могу добавить, чтодумаю, что это объяснение, возможно, немного подло.

Современные СУБД прикладывают большие усилия к планированию и оптимизации запросов, поэтому более не правильно, если вообще когда-либо, что запрос действительно выполняется в определенном порядке.,Насколько я вижу, нет технической причины, по которой оптимизатор не мог смотреть в будущее и включать вычисленные результаты в синтаксический анализ запроса, даже если он предназначен только для замены выражений.

Ну да ладно ...

0 голосов
/ 21 июля 2018
select cost_1, quantity_1, cost_2, quantity_2, 
      cost_1 * quantity_1 as total_1,
      cost_2 * quantity_2 as total_2,
      (cost_1 * quantity_1 + cost_2 * quantity_2) as total_3
from data;
0 голосов
/ 12 января 2012

Вы пытаетесь использовать псевдонимы столбцов в выражении.Если система позволяет вам это делать, это просто синтаксический сахар.Это должно работать на любом диалекте SQL.

select 
 cost_1
,quantity_1
,cost_2
,quantity_2
,cost_1 * quantity_1 as total_1
,cost_2 * quantity_2 as total_2
,(cost_1 * quantity_1) + (cost_2 * quantity_2) as total_3 

from data;
...