2009-07-27 2 views
0

나는 이것이 일반적인 질문이라고 확신하지만 나는 그것을 가장 잘 표현할 방법이 확실하지 않다.SQL : 부모님과 그 자녀를 선택

Questions { Id, Text... } 
Answers { Id, QuestionId, Text...} 

내가 질문의 목록을 검색하고 싶은 결과는 다음과 같이 표시 할 수 있도록 자신의 답변 :

  • 질문

    나는 두 개의 테이블이 A

    • 첫 번째 대답 A
    • ,
    • 두번째 대답은

가 있다고 가정 등 B 을 ... 질문에
  • 질문 B에게
    • 1 대답을 질문에
    • 3 대답을 질문하는이 질문 표의 일부 선택 기준입니다.

      매우 비효율적 인 방법은 모든 관련 질문을 선택한 다음 각각에 대해 모든 대답을 선택하는 것입니다. 또 다른 비효율적 인 방법은 LEFT OUTER JOIN을 사용하는 것입니다.

      질문과 답변을 얻는 가장 효율적이고 간단한 방법은 무엇입니까? 하나의 쿼리로 수행 할 수 있습니까?

  • +2

    왼쪽 외부 조인은 전혀 비효율적이지 않습니다. 왜 당신이 그렇게 생각하는지 모르겠다 – Shawn

    +0

    동의 - 내 대답을 참조하십시오. JOIN은 이러한 목적을위한 것입니다. – Christian

    답변

    2

    MySQL의 경우 (MSSQL이 아님)이 기능이 작동합니다.

    SELECT q.text, a.text 
    FROM questions q 
    LEFT JOIN answers a ON 
        q.quiestionid = q.id 
    GROUP BY q.id, a.id 
    ORDER BY q.id 
    

    q가 있으면 알려주세요.

    +0

    왜 MSSQL에서 작동 할 것이라고 생각하지 않습니까? 방금 ANSI SQL을 작성했습니다. 구문은 SQL Server에서 정상적으로 작동합니다. – Eric

    +1

    afaik, ANSI 준수 rdbms에서는 SELECT 절의 열이 GROUP BY 절에도 나타나야합니다. 그래서 q.text와 a.text는 GROUP BY 절에 포함되어야합니다. 기독교의 예는 PostgreSQL과 MSSQL에서 작동하지 않습니다. 위의 예는 GROUP BY q.id, a.id, q.text, a.text –

    +1

    을 사용하는 pg와 mssql에서만 작동하지만 .id 필드는 기본 키이며 반복되지 않습니다. 쓸데없는 그룹을 놓아 라! –

    1

    왼쪽 결합이 비효율적이라고 생각하는 이유는 무엇입니까? 여러 번 대답 한 질문에 대해 중복 된 데이터를 얻을 수는 있지만 걱정할 필요는 없습니다.

    제안 된 하나의 대답은 잘 작동합니다 (mssql, sqlite 등을 비롯한 모든 실제 SQL 엔진에서 제안 된대로 mysql을 포함하여).하지만 중복되어 있습니다 (기본 키에 ' 어쨌든 중복되지 않습니다.) 그래서 다음과 같은 간단하고 오타 고정 버전은 미세하고 빠른 :

    SELECT q.id, q.text, a.id, a.text 
        FROM questions q 
        LEFT JOIN answers a ON a.questionid = q.id 
    ORDER BY q.id 
    

    클라이언트 코드는 단순히 당신이 원하는대로 "계층"그룹 및 디스플레이 일을 위해 때 q.id 변경 사항을 확인할 수 있어야합니다 - 어떻게 할 그것은 당신이 사용하는 클라이언트 측 언어에 달려 있습니다. 파이썬에서 예를 들어 itertools.groupby을 사용하면 매우 간단합니다 (SQL 서버 측에서 그룹을 필요로하지 않지만 클라이언트 측에서 필요합니다. Python과 같은 언어 제공 기능을 사용하거나 직접 구현하여 원하는대로 계층 구조를 표시 할 수 있습니다.

    +0

    그래, 최악의 경우 20 ~ 100 개의 답변이있을 수 있다고 가정 할 때 비효율적 인 데이터가 중복 된 데이터라고 생각했다. 단순성을 감안할 때, 필자는 성능을 테스트 한 후에 어쨌든 그것을 시도하고 추가 최적화를 연기합니다. – cbp