중첩 된 그룹 바이/핸드 조항과 복잡한 가입?
문제
궁극적으로 각각 하나의 "노래"만있는 "앨범"레코드가 포함 된 "가져 오기"레코드 목록이 필요합니다.
이것이 제가 지금 사용하고있는 것입니다.
select i.id, i.created_at
from imports i
where i.id in (
select a.import_id
from albums a inner join songs s on a.id = s.album_id
group by a.id having 1 = count(s.id)
);
중첩 선택 (조인이있는)은 빠르게 타 오르지 만, "절의 외부"는 극도로 느립니다.
나는 전체 쿼리를 단일 (중첩 없음) 결합하려고했지만 그룹/클로스가있는 문제를 해결하려고 노력했습니다. 내가 할 수있는 최선은 Dupes와 함께 "가져 오기"레코드 목록이었습니다.
이 쿼리를 작성하는 더 우아한 방법이 있습니까?
해결책
어때?
SELECT i.id,
i.created_at
FROM imports i
INNER JOIN (SELECT a.import_id
FROM albums a
INNER JOIN songs s
ON a.id = s.album_id
GROUP BY a.id
HAVING Count(* ) = 1) AS TEMP
ON i.id = TEMP.import_id;
대부분의 데이터베이스 시스템에서 조인은 어디에서 ... in.
다른 팁
SELECT i.id, i.created_at, COUNT(s.album_id)
FROM imports AS i
INNER JOIN albums AS a
ON i.id = a.import_id
INNER JOIN songs AS s
ON a.id = s.album_id
GROUP BY i.id, i.created_at
HAVING COUNT(s.album_id) = 1
(당신은 포함 할 필요가 없을 수도 있습니다 COUNT
에서 SELECT
자체를 나열하십시오. SQL Server는 필요하지 않지만 다른 RDBMS가 가능할 수 있습니다.)
테스트되지 않은 :
select
i.id, i.created_at
from
imports i
where
exists (select *
from
albums a
join
songs s on a.id = s.album_id
where
a.import_id = i.id
group by
a.id
having
count(*) = 1)
또는
select
i.id, i.created_at
from
imports i
where
exists (select *
from
albums a
join
songs s on a.id = s.album_id
group by
a.import_id, a.id
having
count(*) = 1 AND a.import_id = i.id)
세 번의 팽팽한 기술은 모두 다음보다 빠릅니다.
- 관련 하위 쿼리 (GBN)와 함께 존재합니다.
- 내부에 합류 한 하위 쿼리 (Achinda99)
- 세 테이블을 모두 가입하는 내부 (루크)
(모두 작동해야합니다 ... 그래서 그들 모두에게 +1. 그들 중 하나가 작동하지 않는지 알려주십시오!)
실제로 가장 빠른 것으로 밝혀졌으며 데이터와 실행 계획에 따라 다릅니다. 그러나 SQL에서 동일한 것을 표현하는 다른 방법의 흥미로운 예.
나는 전체 쿼리를 단일 (중첩 없음) 결합하려고했지만 그룹/클로스가있는 문제를 해결하려고 노력했습니다.
SQL Server 버전 2005/2008을 사용하는 경우 CTE (Common Table Expression)를 사용하여 하위 쿼리에 가입 할 수 있습니다.
내가 아는 한, CTE는 단순히 하나만 작동하는 가상보기처럼 작동하는 표현입니다. 고르다 진술 - 따라서 다음을 수행 할 수 있습니다. 보통 쿼리 성능을 향상시키기 위해 CTE를 사용합니다.
with AlbumSongs as (
select a.import_id
from albums a inner join songs s on a.id = s.album_id
group by a.id
having 1 = count(s.id)
)
select i.id, i.created_at
from imports i
inner join AlbumSongs A on A.import_id = i.import_id