Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [MySQL] Проблема с запросе с 2-я операторами COUNT, и объеденением таблиц. 
V
    Опции темы
Siriel
Дата 4.2.2009, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 23.9.2008

Репутация: нет
Всего: нет



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

   Допустим есть 3(может и больше таблиц) : 1) школьники; 2) Олимпиада по математике 3) Олимпиаба по физике. Требуется осуществить выборку информации о ученике + сколько раз он участвовал в олимпиадах по физике. 

Запрос примерно сдеующий
Код

SELECT ученики.*, COUNT(олимпиада_по_математике.id_участника) as a, COUNT(олимпиада_по_физике.id_участника) as b
 FROM `ученики` LEFT JOIN `олимпиада_по_математике ` ON (олимпиада_по_математике.id_участника = ученики.id_ученика)
 LEFT JOIN `олимпиада_по_физикеt ` ON (олимпиада_по_физике.id_участника = ученики.id_ученика) GROUP BY ученики.id_ученика


Данный запрос проходит, но в колонках a и b выводятся некорректные результаты (неправильное количество).

Код

SELECT ученики.*, COUNT(олимпиада_по_физике.id_участника) as b
 FROM `ученики` LEFT JOIN `олимпиада_по_физикеt ` ON (олимпиада_по_физике.id_участника = ученики.id_ученика) GROUP BY ученики.id_ученика


Такой запрос (отличается отсутствием выборки из таблицы олимпиада_по_физикеt) выводит в колонку b корректные значения. Подскажите пожалуйста, что делаю не так. Вероятно не правильно понимаю механику SQL...
PM MAIL   Вверх
tzirechnoy
Дата 4.2.2009, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: 2
Всего: 16



<quote> 2) Олимпиада по математике 3) Олимпиаба по физике.</quote>

4) Олимпиада по химии 5) Соревнование на приз директора школы по физкультуре 6) итоговая (годовая) контрольная по географии 7) Вчерашняя контрольная по физике 8) Переписывание вчерашней контрольной по физике...

 Архитектора&nbsp;&mdash; пороть.

По сути&nbsp;&mdash; в аргумент count() начинающим лучшэ ставить *. Меньшэ сбивает с толку.
Запрос свой попробуйте сначала без агрегатов (group by и count()), посмотрите на результат, посчитайте вручную. Чтобы проще было считать&nbsp;&mdash; сделайте это для одного конкретного ученика, как машына и будет считать для каждого из них.
PM MAIL   Вверх
Siriel
Дата 4.2.2009, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 23.9.2008

Репутация: нет
Всего: нет



Архитектура не причем, хотел написать проще для понимания. Если внимательней прочитать первый пост, из него видно, что 2-й запрос работает корректно, то есть с работой операторов GROUP BY и COUNT знаком...
Таблицы могут (и есть) совершенно разными, или это может быть одна таблица из которой требуется выбрать n-наборов под разными условиями, например так:

 Таблицы:
    1) Ученики;
    2) Контрольные работы;

 Требуется выбрать количество пятерок и троек каждого ученика. Выборку вижу в следующем виде (id_ученика, кол-во_троек, колво_пятерок):
Код

 SELECT ученики.id_ученика, COUNT(kr1.id_работы) as тройки, COUNT(kr2.id_работы) as пятерки FROM `ученики`
 LEFT JOIN `контрольные_работы` as kr1 ON (kr1.id_ученика = ученики.id_ученика AND kr1.оценка = '3') 
 LEFT JOIN `контрольные_работы` as kr2 ON (kr2.id_ученика = ученики.id_ученика AND kr2.оценка = '5')
 WHERE ученики.id_ученика = '1' GROUP BY ученики.id_ученика


данный запрос выбирает следующие (некоректные данные) к примеру:

id = 1
тройки = 6
пятерки = 6

а вот такой запрос выбирает корректные данные к тому же примеру:

Код

SELECT ученики.id_ученика, COUNT(kr2.id_работы) as пятерки FROM `ученики`
 LEFT JOIN `контрольные_работы` as kr2 ON (kr2.id_ученика = ученики.id_ученика AND kr2.оценка = '5')
 WHERE ученики.id_ученика = '1' GROUP BY ученики.id_ученика


id = 1
пятерки = 3

Почему так происходит, может кто-нить объяснить?

Это сообщение отредактировал(а) Siriel - 4.2.2009, 14:17
PM MAIL   Вверх
skyboy
Дата 4.2.2009, 14:54 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 15
Всего: 260



Цитата(Siriel @  4.2.2009,  13:15 Найти цитируемый пост)
Почему так происходит, может кто-нить объяснить?

положим, у нас для id = 1 три записи в таблице "контрольные" с оценкой "пятерка" и две записи с оценкой "тройка". в результате у тебя будет 1(запись из "ученики") * 2(запись из "контрольные работы" с оценкой "3") * 3(запись из "контрольные работы" с оценкой "5") = 6 записей, в которой каждая контрольная работа на "5" повторяется дважды, а с оценкой "3" - трижды.
Это называется декартовым произведением и именно так и должен работать join.
PM MAIL   Вверх
Zloxa
Дата 4.2.2009, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Код

SELECT ученики.id_ученика
    , COUNT(case when kr1.оценка = '3' then 1 end) as тройки
    , COUNT(case when kr1.оценка = '5' then 1 end) as пятерки 
FROM `ученики`
 LEFT JOIN `контрольные_работы` as kr1 ON (kr1.id_ученика = ученики.id_ученика AND kr1.оценка in ('3','5')) 
 WHERE ученики.id_ученика = '1' GROUP BY ученики.id_ученика

Код

SELECT ученики.id_ученика, COUNT(distinct kr1.id_работы) as тройки, COUNT(distinct kr2.id_работы) as пятерки FROM `ученики`
 LEFT JOIN `контрольные_работы` as kr1 ON (kr1.id_ученика = ученики.id_ученика AND kr1.оценка = '3') 
 LEFT JOIN `контрольные_работы` as kr2 ON (kr2.id_ученика = ученики.id_ученика AND kr2.оценка = '5')
 WHERE ученики.id_ученика = '1' GROUP BY ученики.id_ученика



--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Siriel
Дата 4.2.2009, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 23.9.2008

Репутация: нет
Всего: нет



Вот это то, - что нужно. Большое спасибо skyboy за объяснение в чем ошибка и Zloxa за правильную реализацию.
Вопрос решен.

Это сообщение отредактировал(а) Siriel - 4.2.2009, 20:12
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Составление SQL-запросов | Следующая тема »


 




[ Время генерации скрипта: 0.0661 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.