2009-08-09 8 views
3

여러 개의 조인이있는 테이블을 선택하려고합니다. 하나는 COUNT를 사용하는 주석의 수이고 다른 하나는 SUM을 사용하여 총 투표 값을 선택하는 것입니다. 문제는 두 조인이 서로 영향을 준다는 것입니다. 게재 :mysql : multiple join problem

3 표 2 개의 댓글

나는이 내가 사용하고 쿼리 3 * 2 = 6 표, 2 * 3 개의 댓글

를 얻을 :

SELECT t.*, COUNT(c.id) as comments, COALESCE(SUM(v.vote), 0) as votes 
FROM (topics t) 
LEFT JOIN comments c ON c.topic_id = t.id 
LEFT JOIN votes v ON v.topic_id = t.id 
WHERE t.id = 9 

답변

3

당신이하는 일은 내가 골드버그 기계을 부르는 SQL 안티 패턴입니다. 단일 SQL 쿼리에서 강제로 문제를 해결하는 것이 왜 그렇게 까다로운가?

SELECT t.*, COUNT(c.id) as comments 
FROM topics t 
LEFT JOIN comments c ON c.topic_id = t.id 
WHERE t.id = 9; 

SELECT t.*, SUM(v.vote) as votes 
FROM topics t 
LEFT JOIN votes v ON v.topic_id = t.id 
WHERE t.id = 9; 

당신이 직교 제품에서이 두 가지 중 하나에 쿼리 결과를 결합 발견으로 : 여기

정말이 문제를 해결할 방법이다. 하나의 쿼리에서 정답을 사용하도록 강제하는 영리하고 미묘한 방법이있을 수 있지만 세 번째 통계가 필요할 때 어떻게됩니까? 두 개의 쿼리에서 수행하는 것이 훨씬 간단합니다.

+0

더 많은 로딩과 데이터베이스 작업이 필요하지 않거나 데이터베이스가 여러 조인을 사용하여 작업을 분리하는 것이 더 힘들지 않습니까? – Dennis

+0

대부분의 데이터베이스에는 데이터 및 인덱스 페이지에 대한 내부 캐싱이 있으므로 문제가되지 않을 수 있습니다. 또한 데카르트 제품을 보완하는 데 필요한 작업이 더 나쁠 수 있습니다. 부분적으로 이는 특정 시스템과 데이터에 따라 다르므로 가장 정확한 대답은 * 사용자 환경에서의 테스트가 필요합니다. –

0
(210)
+0

이제 올바른 수의 설명을 얻지 만 여전히 잘못된 투표 합계를 얻었으므로 v.vote에 DISTINCT를 추가하려고 시도했지만 작동하지 않았습니다. – Dennis

1
SELECT t.*, COUNT(c.id) as comments, COALESCE(SUM(v.vote), 0) as votes 
FROM (topics t) 
LEFT JOIN comments c ON c.topic_id = t.id 
LEFT JOIN votes v ON v.topic_id = t.id 
WHERE t.id = 9 
GROUP BY t.id 

혹은

SELECT `topics`.*, 
(
    SELECT COUNT(*) 
    FROM `comments` 
    WHERE `topic_id` = `topics`.`id` 
) AS `num_comments`, 
(
    SELECT IFNULL(SUM(`vote`), 0) 
    FROM `votes` 
    WHERE `topic_id` = `topics`.`id` 
) AS `vote_total` 
FROM `topics` 
WHERE `id` = 9