Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Есть две таблицы:
Первая таблица:
CREATE TABLE IF NOT EXISTS `table` (
`id_table` int(10) unsigned NOT NULL AUTO_INCREMENT,
...
остальные поля, их много и они в данном случае не важны
...
PRIMARY KEY (`id_table`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
Вторая таблица:
CREATE TABLE IF NOT EXISTS `ocenki` (
`id_table` int(10) unsigned NOT NULL,
`id_otpr` int(10) unsigned NOT NULL,
`ocenka` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`id_table`,`id_otpr`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Нужно отсортировать вывод записей из первой таблице по среднему значению во второй таблице.
Используя интернет и свои пока не богатые познания в MySQL пробовал составлять такие запросы:
$query="SELECT table.*, avg(ocenka) FROM table LEFT JOIN ocenki ON table.id_table=ocenki.id_table GROUP BY table.id_table ORDER BY avg(ocenka) DESC";
$query="SELECT table.*, ifnull(c.s,0) FROM table left join (SELECT id_table, avg(ocenka) AS s FROM ocenki) c ON table.id_table=ocenki.id_table ORDER BY s DESC";
Соответственно оба запроса не работают. Подскажите, как должен выглядеть работающий запрос? Может нужно в моих запросах что-то переделать, или нужно совсем другой запрос писать? Вообщем, буду благодарен за любую помощь)
Отредактированно angelmax (28.10.2011 21:06:31)
Неактивен
$query="SELECT `table`.* FROM `table` left join (SELECT id_table, avg(ocenka) AS s FROM ocenki group by id_table) c ON table.id_table=ocenki.id_table ORDER BY s DESC";
Неактивен
Этот вариант не работает, ничего из БД не извлекается
Неактивен
Неактивен
angelmax написал:
Этот вариант не работает, ничего из БД не извлекается
Да, действительно. Только напечатав пример заметил, что в постах №2 и 4 есть одно существенное отличие. Сами найдете?
Неактивен
Пока я вижу только различия в использовании обратных кавычек - но насколько я знаю их использование/неиспользование непринципиально, и AS после avg. Но я был уверен что использование as обязательно, мне сказали что так же дело добровольное.
Неактивен
table.id_table=с.id_table - в этом разница?
Неактивен
Нет, различие в условии связи (там где ON)
В вашем исходном запросе в условии связи указана таблица ocenki, в то время как джойните вы с таблицей c.
Если бы у вас в скрипте стояла обработка ошибок или предварительно вы тестили запрос непосредственно в бд, то увидели бы текст ошибки, а не "ничего из БД не извлекается".
Неактивен
Все, заработало, спасибо за помощь) Пользуясь случаем так сказать, можете объяснить - as перед псевдонимом дело добровольное, или есть случае когда оно необходимо, его использовать нельзя? И функцию ифнуль здесь использовать не надо? В каких она случаях нужна?
Неактивен
И еще 1 вопрос (сорри за может быть тупые вопросы, просто учусь на практике, предварительно прочитав пару книг по пхп). Как напечатать теперь среднюю оценку? Посылаем запрос, пишем такой цикл: while($row = $results->fetch_assoc()) { ...... } Средняя оценка хранится в массиве с каким ключом?
Неактивен
angelmax написал:
Все, заработало, спасибо за помощь) Пользуясь случаем так сказать, можете объяснить - as перед псевдонимом дело добровольное
Добровольное, но с ним запрос читабельней.
angelmax написал:
И функцию ифнуль здесь использовать не надо? В каких она случаях нужна?
Если в выборке присутствуют null значения, то при сортировке по возрастанию сначала идут null. Если вас не устраивает такой результат, то придется использовать ifnull().
Неактивен
angelmax написал:
И еще 1 вопрос (сорри за может быть тупые вопросы, просто учусь на практике, предварительно прочитав пару книг по пхп). Как напечатать теперь среднюю оценку? Посылаем запрос, пишем такой цикл: while($row = $results->fetch_assoc()) { ...... } Средняя оценка хранится в массиве с каким ключом?
В данном случае ни с каким
В исходной задаче вы поставили "Нужно отсортировать вывод записей из первой таблице", поэтому запрос выбирает только записи из первой таблицы
SELECT `table`.* FROM
Чтобы получить оценку, её нужно включить в список выбираемых полей.
Неактивен
Кстати, что касается использования/неиспользования обратных кавычек, то вопрос может оказаться принципиальным при использовании в качестве имен столбцов,таблиц и т.д. ключевых слов. Сравните:
Неактивен
vasya написал:
angelmax написал:
И еще 1 вопрос (сорри за может быть тупые вопросы, просто учусь на практике, предварительно прочитав пару книг по пхп). Как напечатать теперь среднюю оценку? Посылаем запрос, пишем такой цикл: while($row = $results->fetch_assoc()) { ...... } Средняя оценка хранится в массиве с каким ключом?
В данном случае ни с каким
В исходной задаче вы поставили "Нужно отсортировать вывод записей из первой таблице", поэтому запрос выбирает только записи из первой таблицы
SELECT `table`.* FROM
Чтобы получить оценку, её нужно включить в список выбираемых полей.
То есть, выбирается только то, что стоит перед Фром? Я был уверен, что лефт джойн "дополняет" значения из левой таблицы в данном случае средней оценкой и извлекается с ними... Тогда простите за назойливость, можете подсказать как дополнить запрос, чтобы бы он выбирал еще среднее значение по каждой записи, или это не возможно сделать в 1 запросе?
Неактивен
vasya написал:
Кстати, что касается использования/неиспользования обратных кавычек, то вопрос может оказаться принципиальным при использовании в качестве имен столбцов,таблиц и т.д. ключевых слов. Сравните:
mysql> alter table a add select int;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'selec
t int' at line 1
mysql> alter table a add `select` int;
Query OK, 6 rows affected (0.44 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> select select from a;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'selec
t from a' at line 1
mysql> select `select` from a;
+--------+
| select |
+--------+
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
+--------+
6 rows in set (0.00 sec)
Про ключевые слова я знаю, в принципе я стараюсь всегда поэтому использовать обратные кавычки.
Неактивен
Дополняет, и даже сортирует по значениям средней оценки, но в конечном счете отдает только то, что вы попросили в части перечисления полей (между select и from).
Соответственно, нужно указать все поля какие вы хотите получить:
SELECT table.*, c.s FROM
Кстати, * лучше не использовать, а перечислять поля в явном виде, даже если вам нужны все поля из таблицы. Потом вы добавите в таблицу какое-нибудь текстовое поле, которое не нужно будет выбирать в данном запросе и вряд ли вспомните о необходимости поправить данный запрос.
Неактивен
vasya написал:
Дополняет, и даже сортирует по значениям средней оценки, но в конечном счете отдает только то, что вы попросили в части перечисления полей (между select и from).
Соответственно, нужно указать все поля какие вы хотите получить:
SELECT table.*, c.s FROM
Кстати, * лучше не использовать, а перечислять поля в явном виде, даже если вам нужны все поля из таблицы. Потом вы добавите в таблицу какое-нибудь текстовое поле, которое не нужно будет выбирать в данном запросе и вряд ли вспомните о необходимости поправить данный запрос.
И потом эта средняя оценка хранится в массиве с ключом (в описанном мной случае) $row['c.s'] Или нет? А за совет спасибо, думаю действительно лучше сейчас потратить лишние пару минут, чем потом пару часов)
Практическим путем понял, что ключ - s. Что в принципе логично. И как следствие, если в двух таблицах есть поля с одинаковыми именем и разным значением я их извлекаю оба (опустим причину, вдруг понадобится), то нужно им давать псевдонимы обязательно?
Белых пятен пока много, но с опытом становится все меньше)
Отредактированно angelmax (29.10.2011 00:10:45)
Неактивен
angelmax написал:
И как следствие, если в двух таблицах есть поля с одинаковыми именем и разным значением я их извлекаю оба (опустим причину, вдруг понадобится), то нужно им давать псевдонимы обязательно?
Да.
Неактивен
Спасибо за помощь)
Неактивен
Страниц: 1