2010-01-29 7 views
1

어떻게하면 조인 된 테이블의 결과를 제한 할 MySQL 쿼리를 작성할 것인가? (또는 서브가 더 잘 작동하면 선택 하는가?) 또한 조인 된 테이블의 테이블 개수를 계산합니까?결합 된 테이블의 결과를 제한하고 결합 된 테이블의 항목 수를 계산하는 MySQL 쿼리를 작성하는 방법은 무엇입니까?

예를 들어 프로젝트, 작업 및 주석의 세 가지 테이블이 있다고 가정 해 봅시다. 프로젝트에는 0 개 이상의 작업이 있고 작업에는 0 개 이상의 의견이 있습니다. 프로젝트 당 반환되는 작업 수를 3으로 제한하고 프로젝트 당 총 작업 수와 작업 당 의견 수를 어떻게 반환합니까? 여기

내가 같은 결과 집합 모습을 상상할 수있는 작업은 다음과 같습니다

project_id, project_title, task_id, task_title, num_tasks, num_comments 
------------------------------------------------------------------------ 
1, Project1, 1, Task1, 4, 3 
1, Project1, 2, Task2, 4, 0 
1, Project1, 3, Task3, 4, 9 
2, Project2, 10, Task10, 20, 0 
2, Project2, 11, Task11, 20, 0 
2, Project2, 12, Task12, 20, 2 
3, Project3, 20, Task20, 17, 5 
3, Project3, 21, Task21, 17, 1 
3, Project3, 22, Task22, 17, 2 
는 'Project1의이'등 'Project2에이'단지 등 프로젝트의 제목과 '작업 1', 'Task2를'대표

는 작업의 제목을 나타냅니다 .

궁극적으로 (쿼리의 결과를 분석 한 후) I는 다음과 같이 표시 할 수 싶습니다 (

Project1 (4 tasks) 
    Task1 (3 comments) 
    Task2 (0 comments) 
    Task3 (9 comments) 
Project2 (20 tasks) 
    Task10 (0 comments) 
    Task11 (0 comments) 
    Task12 (2 comments) 
Project3 (17 tasks) 
    Task20 (5 comments) 
    Task21 (1 comments) 
    Task22 (2 comments) 

나는이 하위 선택하여 수행되어야한다 같은데요을하는 괜찮 았어),하지만 난 조인을 사용하여 이것을 달성하는 방법을 알아낼 수 없습니다 그리고 하위에 대한 충분한 핸들이 꽤 이런 일을 선택하지 않습니다.

+0

* 당신에게 프로젝트 당 반환 작업의 수를 제한 할 방법 3 * : 정확히 어느 세 가지를 원하십니까? 예를 들어,'ORDER BY task_id ASC' 또는'ORDER BY num_comments DESC'의 상위 3 개? – BalusC

답변

0

솔직히 말해서, 상관 쿼리를 피하기 위해 다중 쿼리에서이 작업을 수행합니다.

은 그러나 여기 당신은 간다 :

SELECT p.project_id, p.project_title, 
    t1.task_id, t1.task_title, 
    (SELECT COUNT(*) FROM tasks t 
     WHERE t.project_id = p.project_id) AS num_tasks, 
    COALESCE((SELECT COUNT(*) FROM comments c 
     WHERE c.task_id = t1.task_id), 0) AS num_comments 
FROM projects p 
JOIN tasks t1 ON (p.project_id = t1.project_id) 
LEFT OUTER JOIN tasks t2 
    ON (p.project_id = t2.project_id AND t1.task_id > t2.task_id) 
GROUP BY t1.task_id 
HAVING COUNT(*) < 3; 

위 그 ( num_tasksnum_comments) 같은 상관 관계 서브 쿼리가 여러 번 실행해야 함을 고려 - 한 번 t1의 각 행에 대해.

별도로 이러한 쿼리를 실행하고 응용 프로그램 코드의 결과를 결합하여 결과를 얻을 수 있습니다 :

SELECT p.project_id, p.project_title, 
    t1.task_id, t1.task_title 
FROM projects p 
JOIN tasks t1 ON (p.project_id = t1.project_id) 
LEFT OUTER JOIN tasks t2 
    ON (p.project_id = t2.project_id AND t1.task_id > t2.task_id) 
GROUP BY t1.task_id 
HAVING COUNT(*) < 3; 

SELECT task_id, COUNT(*) AS num_comments 
FROM comments 
WHERE task_id IN (...list of task_id values from first query...) 
GROUP BY task_id; 

SELECT project_id, COUNT(*) AS num_tasks 
FROM tasks 
GROUP BY project_id; 

를이 될 수처럼 심지어 세 개의 쿼리를 실행 빠르게 전체보다는 모든 얻는 더 복잡한 쿼리를 실행 함께 결과. 내가 말하고있는 데이터의 양에 달려 있기 때문에 일 수 있습니다. 확실히, 당신은 자신의 데이터베이스를 사용하여 두 솔루션을 테스트해야 할 것입니다. 당신의 후속 질문을 다시


, 나는 하위 쿼리에서이 작업을 수행 할 것 :

SELECT p.project_id, p.project_title, 
    t1.task_id, t1.task_title 
FROM (SELECT * FROM projects ORDER BY last_updated DESC LIMIT 5) p 
. . . 

참고이되지 상관 하위 쿼리 이다; RDBMS는 하위 쿼리를 한 번만 수행하면됩니다.

가장 최근의 프로젝트가 필요하다고 가정했기 때문에 DESC을 사용했습니다.

+0

그래서이 경우 쿼리를 여러 쿼리로 분할 한 다음 스크립팅 언어 (PHP 등)의 개별 결과 집합을 처리하는 것이 더 효율적입니까? 일반적으로 피해야하는 상관 관계가있는 하위 쿼리가 있습니까? –

+0

그것은 많은 의미가 있지만, 나는 원래 질문에 포함시키려는 질문이 하나 더 있습니다. 세 개의 쿼리 집합 중 첫 번째 쿼리에서 반환되는 프로젝트의 총 수를 어떻게 제한할까요? 현재 양식에서는 모든 프로젝트에 대해 최대 세 가지 작업을 반환하지만, 프로젝트 필드 last_updated에 의해 정렬되도록 5 이상으로 제한하고 싶다고합시다. 그건 그렇고, 당신의 모든 도움에 너무 감사드립니다. –

+0

그건 사실 내가 시도한 것과 똑같은 문제이지만, 분명히 MySQL 5.0.45 버전은 서브 쿼리에서 LIMIT를 지원하지 않습니다. –

0

이런 식으로 여러 개의 쿼리와 루프를 사용해야 할 것입니다.
이 방법이 될 수 있지만, 그
가 여기에 내가 달성 줄 방법을 보여 일부 suedo 코드의 내가 가진 :) 시간 이상이

select project_id, project_title from projects 
select project_id, count(*) As num_tasks from tasks group by project_id 
select task_id, count(*) As num_comment from comments group by task_id 

foreach (int projectId in projects.Rows) 
{ 
    select task_id, task_title from tasks where project_id = projectID limit 3 
    foreach (int taskID in tasks.Rows) 
    { 
     select comment_id, comment from comments limit 3 
    } 
} 
관련 문제