2014-12-22 1 views
4

아주 좋은 제목은 아닙니다 (편집 환영합니다)하지만 여기에 요약되어 있습니다. 현재 가지고있는 쿼리는 잘 작동하지만 현재 사용하고있는 것보다 더 쉬운 방법이있을 것입니다. 나는 'QuestionIDFK, Answer, QuestionnaireIDFK'열이있는 테이블 '대답'을 가지고 있습니다. 테이블의 데이터는 사용자가 설문 조사 1과 2에 대한 질문 2에 대한 대답을했다하지만 난이 필요 무엇 설문 조사 3과 4에 대한 질문 2에 대한 답변을 제공하지 않았 음을 의미합니다누락 된 답변이있는 설문 목록을 얻으십시오

QuestionIDFK Answer QuestionnaireIDFK 
1    N   1 
2    N   1 
3    N   1 
1    Y   2 
2    Y   2 
3    Y   2 
1    N   3 
3    N   3 
1    Y   4 
3    Y   4 

같은 것입니다 질문 2에 대한 답변 그래서 예상 출력이없는 질문 ID의 목록은

QuestionnaireWithMissingAnswer2 
3 
4 

내가 잘 작동 아래에이 쿼리를 사용하고 있지만, 더 쉬운 방법이 있는지 궁금하다 :

SELECT distinct a.QuestionnaireIDFK AS QuestionnaireWithMissingAnswer2 
FROM Answer a 
inner join (
SELECT t.QuestionnaireIDFK, 
     STUFF(ISNULL((SELECT ', ' + convert(nvarchar, x.QuestionIDFK) 
       FROM Answer x 
       WHERE x.QuestionnaireIDFK = t.QuestionnaireIDFK 
       GROUP BY x.QuestionIDFK 
       FOR XML PATH (''), TYPE).value('.','VARCHAR(max)'), ''), 1, 2, '') 
       AS QuesList 
    FROM Answer t 
    GROUP BY t.QuestionnaireIDFK) z 
ON z.QuestionnaireIDFK = a.QuestionnaireIDFK AND z.QuesList NOT LIKE '%2%' 
+0

전체 정보를 제공하지 않았습니다. QuestionID 목록과 함께 다른 설문지 테이블이 있어야합니다. 그런 다음 QuestionnaireTable에서 *를 선택하지 않는 이유는 무엇입니까 (선택 *에서 응답). – KumarHarsh

+0

@KumarHarsh 질문 ID에는 '질문'표가 있지만 설문지마다 다른 질문이 있습니다. 하나의 설문지는 10 개의 질문을 갖고, 다른 설문지는 25 개의 질문을 가질 것이고, 당신의 제안은 의미가 있지만 나는 설문지와 답변을 제공 할 수 있습니다. – artm

답변

2

넌 그냥 having 절을 not exists 또는 group by을 사용 :이 질문 # 2 (일부 답변을 적어도 모든 설문)이없는 모든 설문 조사를 얻을 수

select QuestionnaireIDFK 
from answer 
group by QuestionnaireIDFK 
having sum(case when QuestionIDFK = 2 then 1 else 0 end) = 0; 

.

또한 not exists (또는 left outer join)와 함께이 작업을 수행 할 수 있습니다

select distinct QuestionnaireIDFK 
from answer 
where not exists (select 1 
        from answer a2 
        where a.QuestionnaireIDFK = a2.QuestionnaireIDFK and 
         a2.QuestionIDFK = 2 
       ); 

그러나, distinct의 때문에, 이것은 첫 번째 방법보다 더 나은 성능을 가지고 않을 수 있습니다.

1

, 키와 응답 ID 모두에 합류, 다음 where 절을 사용하여 조인 밖으로 성공적으로 필터링 왼쪽 외부 조인을 사용

select q.* 
from Questionnaire q 
left join Answer a on a.QuestionnaireIDFK = q.id 
    and a.QuestionIDFK = 2 
where a.QuestionnaireIDFK is null 

그것은 아주 단정하고 효율적인 쿼리를하게하고, 어디 때문에 작동을 조인을 한 후에 적용되는 절은 조인이 누락 된 경우에만 참일 수 있습니다. "속임수"는 조건을 질문 중에 조건을 조인 조건으로 두는 것입니다. 조인 조건은 조인 중에 평가됩니다 (where 절에서 질문에 조건을 적용하면 효과적으로 내부 조인이됩니다).

또한 우리가 놓친 경우 메인 테이블에서 한 행만 반환되기 때문에 중복되지 않습니다.

또한 설문 조사가 작동하려면 답변이 필요하지 않습니다.

관련 문제