2014-12-09 5 views
0

Я пытаюсь получить количество сколько раз каждой книги происходит в таблице SurveyDatas для каждой оценки и каждого года исследования.Неверный подсчет, используя самообслуживание

В следующем запросе результат в столбце Grade3 для BookId 300 должен быть равен 1, а вместо него - 116. И то же самое для столбца Grade4. Если я удалю Grade4 Count и JOIN, я получу 58, что составляет половину 116, но все же неверно. Я подозрительный, мне нужно использовать подзапрос вместо левых объединений для того, что я пытаюсь сделать здесь, или, возможно, даже более эффективный способ сделать это. Являются ли SQL Server Common Table Expressions здесь полезными? Я никогда не использовал эту функцию.

SELECT sd.SurveyYear, sd.BookId, 
    Count(sd3.Grade) as Grade3, Count(sd4.Grade) as Grade4 
FROM SurveyDatas sd 
LEFT JOIN SurveyDatas sd3 on sd3.BookId = sd.BookId 
    AND sd3.SurveyYear = sd.SurveyYear 
    AND sd3.Grade = '3' 
LEFT JOIN SurveyDatas sd4 on sd4.BookId = sd.BookId 
    AND sd4.SurveyYear = sd.SurveyYear 
    AND sd4.Grade = '4' 
GROUP BY sd.SurveyYear, sd.BookId 

И вот моя структура таблицы и то, что мои данные выглядит, хотя у меня есть больше введенных данных, чем я показываю здесь.

SurveyDataId | SurveyYear | BookId | Grade 
1    2014   300  3 
2    2014   300  4 

ответ

1

Вы получаете декартовую продукцию между двумя. Вместо этого просто используйте условную агрегацию:

SELECT sd.SurveyYear, sd.BookId, 
     sum(case when sd.Grade = '3' then 1 else 0 end) as Grade3, 
     sum(case when sd.Grade = '4' then 1 else 0 end) as Grade4 
FROM SurveyDatas sd 
GROUP BY sd.SurveyYear, sd.BookId; 

Самостоятельное соединение не требуется.

+0

Он отлично работает! Поле My Grade на самом деле является text/varchar для размещения K для детского сада и потому, что мы не делаем расчеты по данным, но это не имеет никакого значения. – HK1

0

Когда вы сами присоединяетесь, вам нужно рассмотреть все столбцы. Вы не используете SurverDataID и не получаете полную картину из-за этого. Включите его в состояние соединения, и вы увидите, чего вы ожидаете.

SELECT sd.SurveyYear, sd.BookId, 
    Count(sd3.Grade) as Grade3, Count(sd4.Grade) as Grade4 
FROM SurveyDatas sd 
LEFT JOIN SurveyDatas sd3 on sd3.BookId = sd.BookId 
    AND sd3.SurveyYear = sd.SurveyYear 
    AND sd3.Grade = '3' 
    AND sd.SurveyDataID = sd3.SurveyDataID -- Add this line 
LEFT JOIN SurveyDatas sd4 on sd4.BookId = sd.BookId 
    AND sd4.SurveyYear = sd.SurveyYear 
    AND sd4.Grade = '4' 
    AND sd.SurveyDataID = sd4.SurveyDataID -- And also this line 
GROUP BY sd.SurveyYear, sd.BookId 

Когда я был в затруднительном положении, я удалил группу, чтобы я мог видеть все строки. Я должен был увидеть нули для класса 4, где опрос был для 3-го класса, и это привело меня к настоящей причине.

Смежные вопросы