Вопрос по sql, postgresql – PostgreSQL повторно использует результат вычисления в запросе выбора

5

Например, используя SQL я могу сделать:

SELECT (a+b) as c FROM table WHERE c < 5 AND (c*c+t) > 100;

Есть ли способ сделать это с помощью Postgres?

a + b это просто пример, в моем случае это расчет расстояния с использованием postgis Yuri Barbashov
Вы не можете просто использовать: SELECT (a + b) ИЗ таблицы WHERE (a + b) & lt; 5 AND ((a + b) * (a + b) + t) & gt; 100; ?? Я понимаю, что было бы проще, как вы предлагаете, но я просто попытался, и это не работает. Federico Cristina

Ваш Ответ

2   ответа
3

SELECT foo.c
FROM (
    SELECT (a+b) as c FROM table
) as foo
WHERE foo.c < 5 
AND (foo.c*foo.c+t) > 100

С точки зрения производительности, я думаю, что это не оптимальное решение (из-за отсутствия предложения WHEREfoo подзапрос, следовательно, возвращая всеtable записи). Я не знаю, выполняет ли Postgresql оптимизацию запросов там.

@YuriBarbashov, вероятно, лучший способ убедиться, что это обернуть вычисление в функцию, и иметь егоRAISE INFO чтобы увидеть, сколько раз его вызывают. Вы также можете поэкспериментировать с настройкой стабильных и неизменных свойств.
Кроме того, попробуйте & quot; Объяснить запрос & quot; функция в pgAdmin для подтверждения комментария @araqnid
Единственная причина, по которой я спросил об этом из-за производительности, и я думаю, что выполнение вычисления расстояния несколько раз в одном запросе не очень хорошо) Yuri Barbashov
я просто проверил это на 100000 записей в дБ, время запроса пропорционально количеству вызовов функции Yuri Barbashov
да, postgresql поймет, чтоfoo.c < 5 на самом деле(table.a+table.b) < 5, если вы установите это в качестве теста и создать индекс на(a+b)вы увидите, что(a+b)<5 отображается как & quot; Index Cond & quot;
8

ни в стандартном SQL. я цитируюруководство здесь:

An output column's name can be used to refer to the column's value in ORDER BY and GROUP BY clauses, but not in the WHERE or HAVING clauses; there you must write out the expression instead.

Можно было бы обсудить стандарт в этом отношении. Хью Дарвен на самом деле идет на многое, делая именно это вЭта статья Я был недавно упомянут.

Вы можете использовать подзапрос, какФедерико предложилилиОбщее табличное выражение (CTE) как это:

WITH y AS (
    SELECT a + b AS c FROM x
    )
SELECT c
FROM   y
WHERE  c < 5
AND    (c*c+t) > 100;

CTE особенно полезны для более сложных операций или если вы хотите повторно использовать промежуточный результат в нескольких (под) запросах.

хм, в mysql это хорошо работает)) Yuri Barbashov
@YuriBarbashov: Есть несколько вещей, которые работают "хорошо" в MySQL - до тех пор, пока они не :)
только около 30% прироста производительности, но лучше, чем ничего) Yuri Barbashov

Похожие вопросы