문제

궁극적으로 각각 하나의 "노래"만있는 "앨범"레코드가 포함 된 "가져 오기"레코드 목록이 필요합니다.

이것이 제가 지금 사용하고있는 것입니다.

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)

세 번의 팽팽한 기술은 모두 다음보다 빠릅니다.

  1. 관련 하위 쿼리 (GBN)와 함께 존재합니다.
  2. 내부에 합류 한 하위 쿼리 (Achinda99)
  3. 세 테이블을 모두 가입하는 내부 (루크)

(모두 작동해야합니다 ... 그래서 그들 모두에게 +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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top