PostgreSQL- 상관 관계 하위 쿼리 실패?
-
06-07-2019 - |
문제
다음과 같은 쿼리가 있습니다.
SELECT t1.id,
(SELECT COUNT(t2.id)
FROM t2
WHERE t2.id = t1.id
) as num_things
FROM t1
WHERE num_things = 5;
목표는 다른 테이블에 5 번 나타나는 모든 요소의 ID를 얻는 것입니다. 그러나이 오류가 발생합니다.
ERROR: column "num_things" does not exist
SQL state: 42703
데이터베이스를 처음 접했기 때문에 아마도 여기서 어리석은 일을하고있을 것입니다. 이 쿼리를 수정하여 액세스 할 수있는 방법이 있습니까? num_things
? 아니면 그렇지 않은 경우이 결과를 달성하는 다른 방법이 있습니까?
해결책
쿼리를 다시 작성할 수 있다고 생각합니다.
SELECT t1.id
FROM t1
WHERE (SELECT COUNT(t2.id)
FROM t2
WHERE t2.id = t1.id
) = 5;
다른 팁
SQL 사용에 대한 몇 가지 중요한 점 :
- WHERE 절에서 열 별명을 사용할 수는 없지만 HADING 절에서는 할 수 있습니다. 그것이 당신이 얻은 오류의 원인입니다.
- 상관 된 하위 쿼리를 사용하는 것보다 Join과 Group을 사용하여 카운트를 더 잘 수행 할 수 있습니다. 훨씬 더 빨라질 것입니다.
- HODIE 조항을 사용하여 그룹을 필터링하십시오.
이 쿼리를 작성하는 방법은 다음과 같습니다.
SELECT t1.id, COUNT(t2.id) AS num_things
FROM t1 JOIN t2 USING (id)
GROUP BY t1.id
HAVING num_things = 5;
이 쿼리가 건너 뛸 수 있다는 것을 알고 있습니다 JOIN
Charles Bretana의 솔루션에서와 같이 T1과 함께. 그러나 나는 당신이 쿼리에 T1의 다른 열을 포함시키기를 원할 것이라고 생각합니다.
Re : 의견의 질문 :
차이점은 WHERE
조항은 전 행에 대해 평가됩니다 GROUP BY
그룹당 그룹을 그룹당 단일 행으로 줄입니다. 그만큼 HAVING
절은 그룹이 형성된 후에 평가됩니다. 예를 들어, 당신은 변경할 수 없습니다 COUNT()
사용하여 그룹의 HAVING
; 그룹 자체 만 배제 할 수 있습니다.
SELECT t1.id, COUNT(t2.id) as num
FROM t1 JOIN t2 USING (id)
WHERE t2.attribute = <value>
GROUP BY t1.id
HAVING num > 5;
위의 쿼리에서 WHERE
조건과 일치하는 행의 필터 및 HAVING
5 개 이상의 카운트가있는 그룹의 필터.
대부분의 사람들이 혼동을 일으키는 요점은 GROUP BY
조항 보인다 처럼 HAVING
그리고 WHERE
상호 교환 가능합니다.
WHERE
선택 목록에서 표현식 전에 평가됩니다. SQL 구문이 SELECT-LIST를 먼저 배치하기 때문에 이것은 분명하지 않을 수 있습니다. 따라서 사용하여 비싼 계산을 많이 절약 할 수 있습니다. WHERE
행을 제한합니다.
SELECT <expensive expressions>
FROM t1
HAVING primaryKey = 1234;
위와 같은 쿼리를 사용하는 경우 Select-List의 표현식이 계산됩니다. 모든 행, HAVING
상태. 그러나 아래 쿼리는 표현식 만 계산합니다. 단일 행 일치합니다 WHERE
상태.
SELECT <expensive expressions>
FROM t1
WHERE primaryKey = 1234;
요약하기 위해 쿼리는 일련의 단계에 따라 데이터베이스 엔진에 의해 실행됩니다.
- 생성 된 행을 포함하여 테이블에서 행 세트를 생성합니다.
JOIN
. - 평가하다
WHERE
행 세트에 대한 조건, 일치하지 않는 행을 필터링합니다. - 행 세트에서 각각에 대한 선택 목록의 표현식을 계산합니다.
- 열 별칭을 적용합니다 (참고 이것은 별도의 단계입니다. 즉, 선택 목록에서 표현식에서 별명을 사용할 수 없습니다).
- 그룹당 단일 행으로 그룹을 응축하십시오.
GROUP BY
절. - 평가하다
HAVING
그룹에 대한 조건, 일치하지 않는 그룹을 필터링합니다. - 에 따라 결과를 정렬합니다
ORDER BY
절.
다른 모든 제안은 효과가 있지만 기본적인 질문에 답하기 위해서는 충분할 것입니다.
SELECT id From T2
Group By Id
Having Count(*) = 5
PostgreSQL에는 조항이있는 경우 별칭 열을 사용할 방법이 없다고 언급하고 싶습니다.
즉
my_id = 1 인 사용자에서 my_id로 usr_id를 선택하십시오.
작동하지 않습니다.
작동하지 않는 또 다른 예 :
su.usr_id로 su.usr_id를 val> = 1으로 su 그룹으로 sys_user에서 val (*)로 su.usr_id를 선택하십시오.
동일한 오류가 발생합니다. VAL 열은 알려져 있지 않습니다.
Bill Karwin이 Postgres에게는 사실이 아닌 것을 썼기 때문에 이것을 높이고 있습니다.
"Where 절에서 열 별명을 사용할 수는 없지만 조항에서는 할 수 있습니다. 이것이 당신이 얻은 오류의 원인입니다."
이 시도
SELECT t1.id,
(SELECT COUNT(t2.id) as myCount
FROM t2
WHERE t2.id = t1.id and myCount=5
) as num_things
FROM t1