2012-06-27 3 views
4

은 내가 할 수있는 SQL을 사용하여 선택 쿼리에서 계산 결과를 재사용?PostgreSQL는 예를 들어

+0

그냥 사용할 수 없습니까? SELECT (a + b) FROM 표 WHERE (a + b) <5 AND ((a + b) * (a + b) + t)> 100; 제안하는 방법이 더 쉬울 것이라고 생각하지만 방금 시도했지만 작동하지 않습니다. –

+1

a + b는 단지 예입니다. 제 경우에는 Postgis를 사용한 거리 계산입니다. –

답변

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 

, 나는 foo는 서브 쿼리의 절, 따라서 반환 WHERE이 때문에의 부족 (최적의 솔루션이없는 것 같아요 모두 레코드). PostgreSQL이 일부 쿼리 최적화를 수행하는지 여부는 알지 못합니다.

+0

성능상의 이유로 그 이유를 묻는 유일한 이유는 동일한 쿼리에서 여러 번 거리 계산을 수행하는 것이 좋지 않다는 것입니다. –

+2

예 postgresql은'foo.c <5'가 실제로'(table.a + table.b) <5'라는 것을 알게 될 것입니다. 이것을 테스트로 설정하고'(a + b)'에 인덱스를 만들면'(a + b) <5'가 "인덱스 인덱스"로 나타납니다. – araqnid

+1

@YuriBarbashov가 아마도 가장 좋은 방법입니다. 함수에서 계산을 래핑하고 호출 된 횟수를 확인하는'RAISE INFO'를해야합니다. 또한 안정적인 속성과 불변의 속성을 그렇게 설정할 수도 있습니다. – araqnid

8

당신은 그렇게 할 수 없습니다. PostgreSQL이나 표준 SQL에서는 그렇지 않습니다. 내가 the manual here 인용 :

출력 컬럼의 이름이 아니라 WHERE 또는 HAVING 절에서, ORDER BYGROUP BY 절에 컬럼의 값을 참조 할 수 있습니다; 대신 표현식을 작성해야합니다.

이 점에 관해서는 논쟁의 여지가있다. Hugh Darwen은 실제로 그것을 수행하는 큰 길이로갑니다. this article 나는 최근에 언급되었습니다.

당신은 Federico suggested, 또는 이런 Common Table Expression (CTE) 같은 하위 쿼리를 사용할 수 있습니다

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

열팽창 계수는 더 복잡한 작업에 특히 유용 또는 여러 개의 (하위) 쿼리의 중간 결과를 다시 사용하려는 경우.

+0

hm, nice에서 작동하는 mysql에서) –

+7

@YuriBarbashov : MySQL에서 "멋지게"작동하는 것들이 많이있다. :) –

+0

약 30 %의 성능 향상 만 있지만 아무것도없는 것보다 낫다) –