2015-07-20 2 views
0

мне нужно вернуть лучшие 5 баллов в каждой категории от table.so пор я попытался запрос ниже следующий пример с этого сайта: selecting top n records per groupMySQL возвращает неправильные результаты со случайными повторяющимися значениями

запроса:

select 
subject_name,substring_index(substring_index 
    (group_concat(exams_scores.admission_no order by exams_scores.score desc),',',value),',',-1) as names, 
    substring_index(substring_index(group_concat(score order by score desc),',',value),',',-1) 
as orderedscore 
from exams_scores,students,subjects,tinyint_asc 
where tinyint_asc.value >=1 and tinyint_asc.value <=5 and exam_id=2 
    and exams_scores.admission_no=students.admission_no and students.form_id=1 and 
exams_scores.subject_code=subjects.subject_code group by exams_scores.subject_code,value; 

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

Как вы можете видеть, английский и математика есть дубликаты, которые не должны быть там

+------------------+-------+--------------+ 
| subject_name  | names | orderedscore | 
+------------------+-------+--------------+ 
| English   | 1500 | 100   | 
| English   | 1500 | 100   | 
| English   | 2491 | 100   | 
| English   | 1501 | 99   | 
| English   | 1111 | 99   | 
|Mathematics  | 1004 | 100   | 
| Mathematics  | 1004 | 100   | 
| Mathematics  | 2722 | 99   | 
| Mathematics  | 2734 | 99   | 
| Mathematics  | 2712 | 99   | 
+-----------------------------------------+ 

Я проверил таблицу и не существует никаких дубликатов

для подтверждения нет никаких дубликатов в таблице:

select * from exams_scores 
    having(exam_id=2) and (subject_code=121) and (admission_no=1004); 

результат:

+------+--------------+---------+--------------+-------+ 
| id | admission_no | exam_id | subject_code | score | 
+------+--------------+---------+--------------+-------+ 
| 4919 | 1004   |  2 |   121 | 100 | 
+------+--------------+---------+--------------+-------+ 
1 row in set (0.00 sec) 

такой же результат для английский язык.

Если я запускаю запрос, как 5 раз, я иногда заканчиваю другим полем, имеющим повторяющиеся значения.

может кто-нибудь сказать мне, почему мой запрос ведет себя этот way..i попытался добавить отчетливый внутри

group_concat(ditinct(exams_scores.admission_no)) 

, но это не работало ??

+1

Просто примечание: вы не должны использовать старый синтаксис соединения, разделенный запятой. Это было единственное, что доступно в 1980-х и начале 90-х годов, но затем явное объединение (INNER JOIN, CROSS JOIN и т. Д.), Где вводится замена старого синтаксиса, подверженного ошибкам. Используйте их вместо этого. –

ответ

1

Вы группируете exams_scores.subject_code, value. Если вы добавите их в выбранные столбцы (...as orderedscore, exams_scores.subject_code, value from...), вы увидите, что все строки различаются по отношению к этим двум столбцам, сгруппированные по ним. Какая правильная семантика GROUP BY.

Редактировать, чтобы уточнить:

  1. Во-первых, сервер SQL удаляет некоторые строки в соответствии с вашим пунктом WHERE.
  2. После этого он группирует оставшиеся строки в соответствии с вашим предложением GROUP BY.
  3. Наконец, он выбирает указанные вами кол-ва, либо путем прямого возврата значения столбца, либо выполнения GROUP_CONCAT на некоторых столбцах и возврата их накопленного значения.

Если выбрать столбцы, не включенные в п GROUP BY, возвращаемые результаты для этих столбцов произвольны, так как сервер SQL уменьшает все строки равны относительно столбцов, указанных в пункте GROUP BY к одной строке - в качестве для остальных столбцов результаты в значительной степени неопределены (отсюда «случайность», которую вы испытываете), потому что - что должен выбрать сервер в качестве значения для этого столбца? Он может выбирать только один случайный случай из всех сокращенных строк.

Фактически, некоторые SQL-серверы не будут выполнять такой запрос и возвращать SQL-ошибку, поскольку результат для этих столбцов будет неопределенным, чего вы не хотите иметь вообще. С этими серверами (я считаю, MSSQL является одним из них), вы более или менее можете иметь только столбцы в вашем SELECT, которые являются частью вашего предложения GROUP BY.

Редактировать 2: Который, наконец, означает, что вам нужно уточнить свой пункт GROUP BY, чтобы получить желаемую группировку.

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