Утро раннее, ты еще не проснулся и не изнасиловал свою голову до состояния кастрюли. Давай вместе думать. Что нужно группировать и зачем? Что с чем нужно объединять и зачем?
Ну смотря где утро ранее. у меня уже 11 часов, скоро скажем так обед. Ну, как мне тут советовали, чтобы посчитать количество голосов, для каждого учителя, надо использовать join и group by и вот ни как я это не понимаю, я по разному пробовал, дома. Но не показывает как надо совсем.
Вот сейчас попробовал такой вот запрос Код (Text): SELECT count(*), id, id_teacher, name_teachers, title_themes FROM `poll_ip`, `teachers` WHERE id=id_teacher group by data Ответ показал такой вот: Сейчас показывает, как мне кажется вроде бы как надо, только вот как значения которые считает функция count запихнуть в переменную и потом вывести на экран.
Как теперь этот запрос вывести в браузер? Код (Text): SELECT count(*), id, id_teacher, name_teachers, title_themes, id_type, ip_address FROM `poll_ip`, `teachers` WHERE id=id_teacher AND id_type=1 group by data order by data asc
Ты очень упорно пропускаешь основы. Есть такое понятие как алиас. Синоним, псевдоним. Когда ты работаешь с агрегированным полем, или когда у тебя в разных таблицах есть поля с одинаковым значением, но разным назначением - не обойтись без алиасинга. Сделай SELECT COUNT(*) `cnt` ... и у тебя в результирующей таблице будет поле cnt.
@denis01 должно быть по SQL92, но mySQL и далее MariaDB вполне допускают пропуск ключевого слова AS. А дальше уже возникает такой элемент, как экономия трафика между приложением и СУБД. Если можно опустить, то почему бы и не сэкономить по 4 байта на каждом вхождении?
Все решилось таким вот кодом, может он и громоздкий, может где-то что-то и не по определенным технологиям, но вроде работает, все как надо. Это наверно главное, я думаю. PHP: <?php $query = "SELECT * FROM `type_teacher`, `teachers` WHERE type_teacher.id=teachers.id_type AND teachers.id_type=1 ORDER BY `name_teachers` ASC"; if($result = mysqli_query($link, $query)) { while($row = mysqli_fetch_assoc($result)) { $query_sql = "SELECT count(*) as count FROM `poll_ip` WHERE id_teacher=".$row["id"]; $result_sql = mysqli_query($link, $query_sql); while($row_sql = mysqli_fetch_assoc($result_sql)) { $query_diagrm = "SELECT count(*) as count FROM `poll_ip`"; $result_diargam = mysqli_query($link, $query_diagrm); while($row_diagram = mysqli_fetch_array($result_diargam)) { $diagrm_all = 100 / $row_diagram['count']; $nbsp = ""; for($i = 0; $i < ($diagrm_all * $row_sql['count']); $i++) { $nbsp = $nbsp." "; } echo '<tr> <td> <span class="teacher">'.$row["name_teachers"].'<span class="themes"> - "'.trim($row["title_themes"]).'"</span></span> <span class="votes"><p>Количество голосов '.$row_sql['count'].' - ('.($diagrm_all * $row_sql['count']).'%)</p></span> <div width="'.($diagrm_all * $row_sql['count']).'%" style="background-color: red; display: inline-block; height: 5px;">'.$nbsp.'</div> </td> </tr>'; } } } } ?>
Фу как это отвратительно. Убери немедленно и иди учи джойны и группировки. Ты не понимаешь что вот это твоё "я сделал" дает нагрузку на сервак. Вот у тебя есть 30 учителей. Будет 1 запрос на их список и еще 30 на их рейтинг. Итого 31. А можно решить за 1. Подчеркиваю, ЗА ОДИН запрос. Люблю приводить пример с десятком яиц. Попросила тебя мамка десяток яиц купить. Ты оделся, вышел на улицу, дошел до остановки, дождался маршрутки, доехал до АШАНа, нашел яйца, взял одно, дошел до кассы, оплатил, дождался маршрутку, доехал и дошел до дома, переоделся, положил яйцо в холодильник, переоделся, вышел на улицу... и так далее пока в холодильнике не будет 10 заветных яиц. А ведь можно весь десяток купить одной упаковкой. Сравни теперь затраты по времени. То же самое и в твоем решении задачи через подзапросы.
Я не спорю, может так и правильнее, как Вы говорите, но я эти джойны и группировки не понимаю. Это пока для меня сложно, давольно. Если Вы можете объяснить это, так чтобы я понял, то я переделаю, но пока я это не понимаю. Сделал так как понял.
У тебя есть таблица в которой каждый кортеж это голос за учителя. Уникальность голоса проверяется по паре дата-айпишник. Но сейчас не о них. Сейчас об учителе. Если сделать группировку по учителю, то можно использовать агрегатную функцию COUNT и посчитать кол-во сгруппированных строк. А по скольку мы группируем по учителю то фактически получаем кол-во голосов за этого учителя. И строк в результате будет столько, сколько уникальных учителей есть в таблице голосований. Это про группировку. Теперь про объединение. У тебя есть таблица учителей с первичным ключом - уникальным идентификатором учителя. И есть таблица голосования в которой голос за учителя определяется по его уникальному идентификатору. То есть, можно объединить таблицу учителей и таблицу голосования через уникальный идентификатор учителя. Ну и самое интересное это комбинирование группировки и объединения. Одним запросом ты можешь выбрать нужную тебе информацию по учителю - например, айдишник и фио, и тут же подцепить вторую таблицу, сделать по ней группировку и агрегатом посчитать кол-во сгруппированных строк. На выходе ты получаешь одну таблицу с полями айдишникУчителя+ФИОУчителя+КолвоГолосовЗаУчителя. Это одна из самых простых задач с группировкой и объединением. Думаю, можно даже примеры похожие найти и просто адаптировать их под свой случай.
Я вот такие примеры не находил, все что мне попадалось, это по отдельности join и по отдельности group by а вот как они вместе сочитаются нигде не видел.
В них должно быть объяснение, теория, основы, практика, причинно следственные связи. Чтобы ты смог написать запрос, которого нет в документации. Понимая принципы работы базы.
@kvadim вместе они работают ровно так же легко как и по отдельности. Напиши сначала запрос с группировкой - вывод кол-ва строк с каждым из учителей. А потом например через джойн выведи дату последнего голоса. Давай, дерзай. Ждем от тебя два запроса по заданию.
ерунда это будет, а не голосование. у нашего домашнего интернет-провайдера, например, тысяч 50 квартир и очень небольшой пул внешних адресов. чем более локальным будет твой сайт, тем больше лучей ненависти ты заработаешь. а если не учтешь, что бывают еще браузерные "оптимизаторы трафика", которые работают как прокси, можешь получить до 30% одинаковых адресов вообще.
С группировкой какая-то белеберда получается, выдает не то что нужно, ну не понимаю я это...и все....хрень какая-то эта группировка вместе джойном.......У меня вышло такая вот ерунда Код (Text): SELECT count(*) AS count, name_teachers, title_themes FROM `poll_ip`, `teachers` GROUP BY name_teachers С таким запросом выдает у всех 30 учителей одинаковое количество 34, это 34 голоса было. Еще попробовал сделать так Код (Text): SELECT count(*) AS count, name_teachers, title_themes FROM `poll_ip` inner join teachers on poll_ip.id_teacher = teachers.id GROUP BY name_teachers Так выдает только тех за кого проголосовали, правда количество голосов у всех разный, а за кого не проголосовали не показывает, а так не должно быть. А вот так выдает все тоже самое, только сортирует по дате Код (Text): SELECT count(*) AS count, name_teachers, title_themes, data FROM `poll_ip` inner join teachers on poll_ip.id_teacher = teachers.id GROUP BY name_teachers ORDER BY data DESC
Мдя... Бяда... Первый способ называется умножением таблиц. Для каждой строки первой таблицы будет подставлена каждая строка второй таблицы. Потом ты схлопнешь джойном и получишь одинаковые суммы. Всё работает как и должно. Второй способ, равно как и третий, используют тип объединения, при котором не допускается отсутствие кортежей в связанной таблице. Поэтому у тебя в результирующей таблице нет учителей, за которых нет голосов. Все работает как и должно.
Спасибо, за подсказки, но все равно это не то, что надо. Может так и должно быть по Вашему, но меня такой результат не устраивает. Так не должно быть! Надо, чтобы не только отображались голоса за которых проголосовали, но и те за которых не голосовали. А так выходит однобокая картина. Так как я сделал, показывает, так как надо.
Не-не-не. Оно не по моему так. Оно ТАК работает потому что ТЫ ТАК написал. И оно работает ПРАВИЛЬНО. Но... Если тебя не устраивает результат - ПЕРЕПИШИ. Задача реально тривиальная. Ты слишком много сил на неё тратишь. Может уже стоит забыть про программирование? Ну не твоё это, видимо.
Если у Вас больше опыта, а у меня меньше, то это не значит, что мне надо все бросать и забывать. Просто учителей реально практикующих и нормально объясняющих мне не встречалось, все как-то сам. По чуть-чуть. И еще если сейчас у меня все работает, так как мне надо, то зачем переписывать? Главное результат, а по какой технологии это не важно. Я так думаю. Я могу конечно и ошибаться. Но пока все работает, так как надо. Голоса по каждому показывает, даже еще и процентное соотношение. И еще раз повторюсь, если Вы лучше понимаете это дело, так объясните, так чтобы было понятно, тем у кого опыта мало.
Для решения твоей задачи одним запросом нужно просто еще разок внимательно прочитать про объединения.
читай про разницу между inner join и outer (left|right) join. ты объединяешь учителей с голосованием как inner join. результат включает только те записи, для которых есть соответствие в обеих таблицах! то есть никаких "пустых" голосований ты здесь не получишь. вот так оно работает, просто запомни. тебе поможет внешнее соединение. гугли "mysql внешнее соединение"