2012-09-20 5 views
0

나는 4 개의 테이블 a,b,c,d을 가지고 있습니다. 표 a에는 id, name의 쌍이 있습니다. 표 b에 나는 idx, idy의 쌍을 가지고 있습니다. b.idya.id 테이블에서 제공됩니다. 테이블 c, d에는 테이블 b.idx과 관련된 id, value의 쌍이 있습니다.단순하지만 중첩 된 SELECT 쿼리

은이 같은 쿼리를 수행해야합니다

SELECT c.value, d.value 
FROM a,b,c,d 
WHERE a.name = "test" AND b.idy = a.id AND (c.id = b.idx AND d.id = b.idx) 

문제는 때때로이 너무 AND 제로 레코드를 반환합니다 c, d 테이블에없는 기록이 있지만에서 중 사용할 수있는 경우 내가 결과를 가질 필요가 c 또는 d. 또한 OR 두 테이블에 대해 다른 행을 반환하기 때문에 사용할 수 없습니다.

UNION을 사용하거나 심지어 중첩 된 SELECT을 사용하는 솔루션이 있다고 생각합니다. 나는 JOIN을 사용하지 않거나 분리 된 quires를 사용하는 것을 선호합니다.

미리 감사드립니다.

업데이트 :

JOIN 성능이다 사용 피하는 이유. 지금 작업하고있는 구조는 이보다 훨씬 복잡하므로 JOIN으로는 향후 성능에 심각한 문제가있을 것이라고 확신합니다.

+2

왜 조인을 선호하지 않는가? 이것은 고전적인 LEFT JOIN 사용 사례로 보입니다. – Vikdor

+0

원래 게시물의 이유를 설명했습니다 – Mahdi

+1

그리고 실제로 당신은 이미 JOIN을 사용하고 있습니다. 'FROM a, b, c, d '는 무엇을 의미한다고 생각하니? 성능에 관해서는, "올바른 결과를 얻지 못했습니다"심각한 성능 문제처럼 보입니다. – LSerni

답변

1

나는 당신이 LEFT JOIN 사용하려는 생각 : 쉼표 조인 구문을 사용

SELECT c.value, d.value 
FROM a 
LEFT JOIN b 
    ON a.id = b.idy 
LEFT JOIN c 
    ON b.idx = c.id 
LEFT JOIN d 
    ON b.idx = d.id 
WHERE a.name = "test" 

을 레코드가 모든 테이블에서 사용할 수 있음을 필요로하는 INNER JOIN입니다.

당신이 유용한 가이드가 JOIN 구문을 검토에 도움이 필요한 경우 :

A Visual Explanation of SQL Joins

+0

감사합니다 bluefeet! 작동하고있어 'RedFilter'솔루션보다 약간 빠릅니다. 왜 그런지 알고 있니? – Mahdi

1
select c.value, d.value 
from a 
inner join b on b.idy = a.id 
left outer join c on c.id = b.idx 
left outer join d on d.id = b.idx 
where a.name = "test" 
    and coalesce(c.id, d.id) is not null 
+0

감사합니다. RedFilter, 나는 당신의 쿼리를 테스트합니다. :) ... 다른 답변을 테스트 할 것입니다 ... – Mahdi

+1

@Mahdi 제 쿼리의 기능을 명확히하기 위해 'a' * 및 * b'테이블과 일치하는 레코드와 'c' * 또는 *'d'. – RedFilter

+0

예, 'bluefeet'검색어보다 약간 느립니다. 왜 그런지 알아? 쿼리를 사용하면 어떤 이점이 있습니까? 다시 한 번 감사드립니다! – Mahdi

1
SELECT c.value, d.value 
FROM a,b,c,d 
WHERE a.name = "test" AND b.idy = a.id AND (c.id = b.idx AND d.id = b.idx) 
UNION 
SELECT c.value, NULL 
FROM a,b,c 
WHERE a.name = "test" AND b.idy = a.id AND c.id = b.idx AND NOT EXISTS(SELECT NULL FROM d where d.id = b.idx) 
UNION 
SELECT NULL, d.value 
FROM a,b,d 
WHERE a.name = "test" AND b.idy = a.id AND d.id = b.idx AND NOT EXISTS(SELECT NULL FROM c where c.id = b.idx) 
+0

JosephH 감사합니다! 검색어가 작동하지만 다른 검색어보다 몇 배 느립니다. 그러나 'UNION'또는 중첩 된 SELECT를 통해 요청했음을 알고 있습니다. 어쨌든 고마워요! :) – Mahdi

+1

@Mahdi이 사용의 주요 이점은 행이 c 또는 d에 없을 때'(NULL) '값을 설정할 수 있다는 것입니다. 내가 아는 한, 당신이'JOIN'을 사용하는 것이 가능하지 않다고 생각합니다. – JosephH

+0

죄송합니다. 정확히 무엇을 의미하는지 이해할 수 없습니다. ... 좀 더 설명해 주시겠습니까? 감사합니다. – Mahdi