|
|
|
| Добрый день.
Помогите, пожалуйста, довести до ума запрос.
есть две таблицы, первая это группы фотографий(всего 3), вторая это фотографии для определённой группы. вторая таблица привязана к первой по id записи в первой таблице.
во второй таблице есть поле "quote" куда заносятся результаты голосования для фото, по умолчанию значение поля равно 0, при каждом голосовании значение увеличивается на 1.
надо вывести на страницу три записи так, что бы для каждой группы выводилось одно фото, с максимальным значением поля quote.
попробовал сделать запрос к двум таблицам сразу, записи выводятся, но не так как надо.
SELECT `contest_cat`.`name` AS `name`,
`contest_cat`.`id_contest_cat` AS `id_contest_cat`,
`contest`.`id_contest` AS `id_us`,
`contest`.`titleph` AS `title`,
`contest`.`small` AS `small`,
`contest`.`big` AS `big`,
MAX(`contest`.`quote`) AS `quote`
FROM `contest_cat`,`contest`
WHERE `contest`.`id_contest_cat` = `contest_cat`.`id_contest_cat`
AND `contest`.`hide` = 'show'
AND `contest_cat`.`hide` = 'show'
GROUP BY `quote`
ORDER BY `quote` LIMIT 3
|
contes_cat таблица с группами, contest это таблица с фотографиями для определённой группы.
при таком запросе выводится фото только для двух групп и не с максимальным значением поля quote, для третьей группы вообще ни чего не выводится.
короче, запутался окончательно, подскажите, как правильно сделать? | |
|
|
|
|
|
|
|
для: Slo_Nik
(16.12.2009 в 12:57)
| | У вас должно быть соединение таблиц через LEFT JOIN. А второй таблицы contest в запросе нет. | |
|
|
|
|
|
|
|
для: Лена
(16.12.2009 в 13:17)
| | не понял, как нет второй таблицы? | |
|
|
|
|
|
|
|
для: Лена
(16.12.2009 в 13:17)
| | Есть, да только как обычно, через запятую... | |
|
|
|
|
|
|
|
для: Trianon
(16.12.2009 в 13:30)
| | в таком случае как запятая влияет на запрос? | |
|
|
|
|
|
|
|
для: Slo_Nik
(16.12.2009 в 13:38)
| | Не дает создать внешне левостороннее соединение.
Вынуждает делать его внутренним. Что, по Вашему описанию, проблему не решает.
(Ну это помимо идеи о деревянных пулях) | |
|
|
|
|
|
|
|
для: Slo_Nik
(16.12.2009 в 13:38)
| | Забыл сказать, это не основная проблема.
Главное - Ваш запрос неоднозначен по GROUP BY - он в разделе SELECT перечисляет негруппирующие поля за рамками агрегатных функций. Так писать нельзя (хоть сервер MySQL и позволяет), поскольку никакого разумного результата такой запрос не вернет.
Очень грубый пример:
SELECT a, MAX(b), с, d
FROM tbl
GROUP BY a, d;
|
В списке SELECT 4 поля : a, b, c и d.
Поле a и d писать можно, поскольку они группирующие ( перечислены в GROUP BY),
поле b писать можно, поскольку оно является параметром агрегатной функции MAX(),
поле с писать нельзя, поскольку его нет ни там, ни там. Его значение неоднозначно. | |
|
|
|
|
|
|
|
для: Trianon
(16.12.2009 в 14:10)
| | тогда как быть, если помимо группирирующих параметров мне надо получить ещё и те которые за рамками агрегатных функций?
т.е. мне надо вывести "имя группы"(всего 3) +id группы и для каждой группы одно фото, где quote максимально + пути к фото + id фото ?
у меня сейчас получается вывод
1-я группа + 1-но фото с max quote, quote не принадлежит этому фото
2-я группа + 1-но фото с max quote, quote не принадлежит этому фото
2-я группа + 1-но фото с max quote, quote не принадлежит этому фото
а надо
1-я группа + 1-но фото с max quote
2-я группа + 1-но фото с max quote
3-я группа + 1-но фото с max quote | |
|
|
|
|
|
|
|
для: Slo_Nik
(16.12.2009 в 15:19)
| | а группирование по какому полю требуется?
От него и отталкиваться.
Остальные поля подключать соединением с таблицей.
вот здесь я описал | |
|
|
|
|
|
|
|
для: Trianon
(16.12.2009 в 15:41)
| | как я понимаю, группировать надо не по одному полю.
вывести группы, к каждой привязать одно фото из группы с максимальным quote
вот здесь я и запутался, не могу ни как в голове сложить как лучше группировать... | |
|
|
|
|
|
|
|
для: Slo_Nik
(16.12.2009 в 16:44)
| | В принципе, бывают случаи, когда требуется группировать запрос по нескольким полям.
Но у Вас-то фактор группировки один? | |
|
|
|
|
|
|
|
для: Trianon
(16.12.2009 в 16:48)
| | группировать да, по полю quote, надо получить с максимальным значением.
а сортировка, если фото с одинаковым значением quote две и более, то сортировать по id .
если я заблуждаюсь по поводу группировки, то поправьте меня. | |
|
|
|
|
|
|
|
для: Slo_Nik
(16.12.2009 в 18:03)
| | Приведите структуру таблиц (а то непонятно даже в какой таблице у Вас quote и какого типа. )
SHOW CREATE TABLE contest;
и т.п.
И напишите простой запрос, в котором Вы вытаскиваете сгруппированное quote и значения агрегатных функций. И всё.
Следующий шаг - потом.
Всякие остальные поля, любые сортировки - всё позднее. | |
|
|
|
|
|
|
|
для: Trianon
(16.12.2009 в 23:10)
| | таблица с фотографиями(здесь находится quote)
+----------------+---------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------------+------+-----+---------------------+----------------+
| id_contest | int(8) | NO | PRI | NULL | auto_increment |
| author | tinytext | NO | | |
|
| email | tinytext | YES | | NULL |
|
| titleph | tinytext | YES | | NULL |
|
| small | tinytext | NO | | |
|
| big | tinytext | NO | | |
|
| hide | enum('show','hide') | NO | | hide |
|
| quote | int(10) | NO | | 0 |
|
| date | datetime | YES | | 0000-00-00 00:00:00 |
|
| id_contest_cat | int(11) | NO | | 0 |
|
+----------------+---------------------+------+-----+---------------------+----------------+
таблица групп фотографий
+----------------+---------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------------+------+-----+---------------------+----------------+
| id_contest_cat | int(8) | NO | PRI | NULL | auto_increment |
| name | tinytext | NO | | |
|
| description | text | NO | | |
|
| hide | enum('show','hide') | NO | | hide |
|
| data | datetime | NO | | 0000-00-00 00:00:00 | |
+----------------+---------------------+------+-----+---------------------+----------------+
SELECT `id_contest`, MAX(`quote`) AS mquote FROM `contest` GROUP BY `quote` LIMIT 3
одну группу пропустил, хотя должно быть все три, по одной фото от каждой.
3 группа
d_contest = 56
mquote = 2
1 группа
id_contest = 62
mquote = 9
1 группа
id_contest = 64
mquote = 10 | |
|
|
|
|
|
|
|
для: Slo_Nik
(17.12.2009 в 01:31)
| | Вам так трудно было выполнить запросы
SHOW CREATE TABLE contest;
SHOW CREATE TABLE contest_cat;
и привести результаты здесь?
Зачем этот изврат?
Или Вы полагаете что по этим, с позволения сказать, чертежам восстановить таблицы проще?
И таки Вы уверены, что группирование ведется по quote, а не по id_contest_cat?
Потому что SELECT MAX(aaa) FROM tbl GROUP BY aaa - это чушь.
Понимаете, нет смысла спрашивать какой максимум в колонке aaa, разделив весь набор на группы с равными значениями aaa .
Если значения в группе все равны, то и максимум будет равен значению, и минимум, и вообще любой элемент.
Похоже, помимо структуры, придется привести еще и фрагмент дампа данных. | |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 01:38)
| | CREATE TABLE `contest` (
`id_contest` INT(8) NOT NULL AUTO_INCREMENT,
`author` TINYTEXT NOT NULL,
`email` TINYTEXT,
`titleph` TINYTEXT,
`small` TINYTEXT NOT NULL,
`big` TINYTEXT NOT NULL,
`hide` ENUM('show','hide') NOT NULL DEFAULT 'hide',
`quote` INT(10) NOT NULL DEFAULT '0',
`date` DATETIME DEFAULT '0000-00-00 00:00:00',
`id_contest_cat` INT(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id_contest`)
)ENGINE=MyISAM DEFAULT CHARSET=cp1251;
CREATE TABLE `contest_cat` (
`id_contest_cat` INT(8) NOT NULL AUTO_INCREMENT,
`name` TINYTEXT NOT NULL,
`description` TEXT NOT NULL,
`hide` ENUM('show','hide') NOT NULL DEFAULT 'hide',
`data` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id_contest_cat`)
)ENGINE=MyISAM DEFAULT CHARSET=cp1251; | |
|
|
|
|
|
|
|
для: Slo_Nik
(17.12.2009 в 01:55)
| | Спасибо. Замечательно.
Дамп данных делается в phpMyAdmin на закладке Экспорт.
Прикрепить лучше архивом. | |
|
|
|
|
 1.3 Кб |
|
|
для: Trianon
(17.12.2009 в 02:02)
| | Это не дамп, Вас не устроил "чертёж", вот и прикрепил структуру.
теперь прикрепил дамп.
изменил запрос, как посоветовали, теперь выводит по одной фото из каждой группы, но значения quote не соответсвуют фотографиям.
группировал по id_contest_cat
p.s. удалил из дампа одну таблицу, которая не имеет отношения к вопросу
а вот с базой по моему проблемка есть, после Вашей просьбы сделать дам рассмотрел одну фигню....
в таблице contest primary key есть , вот key не указан мной ... | |
|
|
|
|
|
|
|
для: Slo_Nik
(17.12.2009 в 02:16)
| | >Это не дамп, Вас не устроил "чертёж", вот и прикрепил структуру.
Всё правильно. Я структуру и просил сперва. И дамп тоже. Потом.
На будущее. Когда описываете проблему со сложным запросом - с этого надо начать.
Так прямо и написать. Дамп структуры и данных прикрепляю.
>теперь прикрепил дамп.
>изменил запрос, как посоветовали,
И где он , этот свежий вариант? Который
теперь выводит по одной фото из каждой группы, но значения quote не соответсвуют фотографиям.
Показывайте.
Напомню:
напишите простой запрос, в котором Вы вытаскиваете группирующее значение и значения агрегатных функций. И всё.
Следующий шаг - потом.
>группировал по id_contest_cat
То есть так всё же не по quote. Уже хорошо. | |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 02:37)
| | Запрос
SELECT `id_contest`, MAX(`quote`) FROM `contest` GROUP BY `id_contest_cat` LIMIT 3
Выводит
1-я группа
id_contest = 62 (64)
MAX(`quote`) = 10
2-я группа
id_contest = 67 (55)
MAX(`quote`) = 2
3-я группа
id_contest = 68 (56)
MAX(`quote`) = 2
в скобках указаны значения id_contest которые должны быть при получении результатов запроса | |
|
|
|
|
|
|
|
для: Slo_Nik
(17.12.2009 в 02:46)
| | Я же вроде пояснил, что id_contest в списке SELECT быть не должно. Только группирующие поля (это у вас `id_contest_cat` - он один в GROUP BY) и агрегаты ( это у Вас MAX(`quote`) )
И никаких лимитов. Все сортировки лимиты и прочие фенечки ПОЗЖЕ!!!!
Итак (я добавил алиас для удобства):
SELECT `id_contest_cat`, MAX(`quote`) AS`maxquote`
FROM `contest`
GROUP BY `id_contest_cat`
|
Вас устраивает вывод этого запроса по данным? Он правильно считает?
id_contest_cat maxquote
15 10
16 2
17 2
|
| |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 02:56)
| | проверил, считает правильно
вот как теперь привязать id_contest к этому? | |
|
|
|
|
|
|
|
для: Slo_Nik
(17.12.2009 в 03:03)
| | Теперь, когда агрегаты посчитаны, рассказывайте, какие еще поля у каких таблиц Вы хотели получить.
Кроме номера категории и максимума quote для этой категории. Слово группа (хоть у Вас сущность так называется) не применяю, дабы не вносить терминологическую путаницу.
Какая именно из id_contest нужна для каждой из трех строк и почему? | |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 03:09)
| | из таблицы contest_cat надо получить id_contest_cat и name, для того, что бы вывести название группы, а потом передать эти значения методом get, сортировать надо по полю hide
из таблицы contest надо получить small, quote, titleph, сортировать по полю hide
для каждой строки нужна та id_contest которой соответсвует максимальное quote, опять же для передачи методом get на другую страницу где выводятся все фотографии группы, что бы отдельно от всех фото разместить фото лидера.
вот ссылка для наглядности. | |
|
|
|
|
|
|
|
для: Slo_Nik
(17.12.2009 в 03:21)
| | >из таблицы contest_cat надо получить id_contest_cat и name, для того, что бы вывести название группы, а потом передать эти значения методом get
C этим просто. LEFT JOIN результата с таблицей contest_cat по условию равенства ключей и вытаскивайте что хотите.
>из таблицы contest надо получить small, quote, titleph
Вы пока что даже первичный ключ (id_contest) не получили, а уже за остальными гонитесь.
С полем quote более менее ясно - это посчитанный по категориям максимум.
А какой именно id_contest ему соответствует?
id_contest
id_contest_cat quote
15 64 10
15 62 9
15 63 2
16 55 2
16 66 1
16 67 0
17 56 2
17 65 1
17 68 0
|
С 15-й категорией более менее понятно . фотография нужна с quote = 10 и она одна (64).
А 16 и 17 категории? Там как?
UPD. Хотя там тоже однозначно.
Но что Вы будете если будут две двойки в пределах одной категории - что делать?
представьте, что строка 16 - 66 тоже набрала двойку. | |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 03:31)
| | все id_contest соответствуют quote
15 надо получить id_contest 64
16 ----------------//----------------- 55
17 ----------------//----------------- 56
вот эти три фото надо вывести на главной.
насчёт совпадения quote в одной категории я думал и как понимаю distinct тут не поможет.
наверное надо будет добавлять ещё одно поле в contest , голоса принимать от 1 до 5 и потом уже высчитывать среднее значение для каждой фото.
или есть варианты? | |
|
|
|
|
|
|
|
для: Slo_Nik
(17.12.2009 в 03:50)
| | Вы не с того конца думаете.
Забудьте на минуту про SQL.
Вы же там конкурс проводите.
Вот набирают два человека одно и то же (максимальное) число голосов.
Кого из них Вы покажете?
Что будете делать с лицом (своим), после того, как тот, кого из них Вы не покажете, Вам его набьет?
Нет, если казать надо обоих, то нет вопросов. Получается простейший запрос.
Но если одного - то с условиями Вы что-то недодумали.
PS. Голос , кстати, по-аглицки не quote, а vote. | |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 03:54)
| | >PS. Голос , кстати, по-аглицки не quote, а vote.
я в курсе, но это не главное :), написал сначала quote, а потом не стал исправлять, так и осталось.
>Вот набирают два человека одно и то же (максимальное) число голосов.
значит надо всётаки добавлять одно поле в таблицу, и диапозон при голосовании делать от 1 до 5...
или, например, добавлять время голосования и тогда уже по времени выбирать лидера, за кого последнего проголосовали, то и лидер... | |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 03:54)
| | Trianon, спасибо, что то начало получаться, но додумаю завтра.... | |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 03:31)
| | рано обрадовался :(
с таблицей contest_cat действительно без проблем, все нужные значения получил, а вот с таблицей contest ни как не могу разобраться, не пойму как получить нужные значения id_contest , small, titleph
SELECT `con2`.`id_contest_cat`,
MAX(`con2`.`quote`) AS `mquote`,
`con1`.`name` AS `name`,
`con2`.`titleph` AS `title`,
`con2`.`id_contest` AS `id_us`
FROM `contest` AS `con2`
LEFT JOIN `contest_cat` AS `con1` ON `con1`.`id_contest_cat` = `con2`.`id_contest_cat`
GROUP BY `id_contest_cat`
|
вот что я накрутил, но .... | |
|
|
|
|
|
|
|
для: Slo_Nik
(17.12.2009 в 15:17)
| | исправляйте. Учитывая сказанное (16.12.2009 в 14:10) и по ссылке в (16.12.2009 в 15:41) | |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 18:48)
| | хорошо, вот запрос
SELECT `contest`.`id_contest_cat`,
MAX(`contest`.`quote`) AS `mquote`,
`contest`.`id_contest` AS `id_contest`,
`contest_cat`.`name` AS `name`
FROM `contest_cat`
LEFT JOIN `contest` ON `contest`.`id_contest_cat` = `contest_cat`.`id_contest_cat`
GROUP BY `id_contest_cat`
|
при таком запросе у меня выводит правильно название группы фотографий и quote, хотя если следовать Вашим рекомендациям от 16.12.09 в 14.10, то получается, что `contest_cat`.`name` AS `name` я не могу писать, т.к. оно ни где не присутствует, ни в группирирующих ни в агрегатной, но это всёравно мне даёт имя группы фотографий.
если я допишу в GROUP id_contest, то будет вывод всех фотографий.
я не могу понять как всё таки получить id_contest для извлечения остальных полей нужной фотографии,самого изображения, названия...? | |
|
|
|
|
|
|
|
для: Slo_Nik
(17.12.2009 в 19:41)
| | >хорошо, вот запрос
>
>SELECT `contest`.`id_contest_cat`,
> MAX(`contest`.`quote`) AS `mquote`,
> `contest`.`id_contest` AS `id_contest`,
> `contest_cat`.`name` AS `name`
> FROM `contest_cat`
> LEFT JOIN `contest` ON `contest`.`id_contest_cat` = `contest_cat`.`id_contest_cat`
> GROUP BY `id_contest_cat`
>
|
Что хорошо, что?
Сказал же: В списке селект агрегатного запроса не должно присутствовать ничего кроме того, что в GROUP BY, и того что внутри MAX() !
Трижды уже сказал, если не больше!!
Почему появилось еще два поля, которые этому условию не отвечают?!
Отдельный вопрос. Почему поле в GROUP BY не уточнено именем таблицы? | |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 20:15)
| | значит правильно понял, не должно присутствовать, но подставив в запрос `contest_cat`.`name` AS `name` - получил имя группы фотографий, это первое, что я не могу понять.
прочитал по Вашей ссылке, рылся в мануале, но так и не смог понять как вытянуть остальные параметры. с чем связать contest.id_contest что бы вытянуть из таблицы и уже к этому привязывать остальные параметры?
поле в GROUP уточнил именем таблицы contest_cat
возможно надо сделать к таблице contest вложеный запрос? или я опять не туда думаю? | |
|
|
|
|
|
|
|
для: Slo_Nik
(17.12.2009 в 20:38)
| | >значит правильно понял, не должно присутствовать, но подставив в запрос `contest_cat`.`name` AS `name` - получил имя группы фотографий, это первое, что я не могу понять.
Да. В некоторых случаях Вы в MySQL сможете получить и другие поля, и даже без неоднозначности.
Почему в некоторых - потому что в случаях однозначной ключевой зависимости от группирующего поля.
У Вас `contest_cat`.`name` (точнее все поля таблицы `contest_cat`) однозначно определяется первичным ключом этой таблицы, по которому и идет группировка. Вот поэтому с этим полем всё хорошо. А с остальными плохо. Потому что ключевой зависимости нет.
Почему MySQL - потому что любой другой нормальный SQL-сервер такой запрос отвергнет, как ошибочный, и чихать ему на зависимости. Писать запросы нужно корректно.
Вам сейчас нужно научиться писать запросы в строгом виде, невзирая на ключевые зависимости.
Научитесь писать строго - писать попроще всегда сможете. Поэтому `contest_cat`.`name` убирайте, несмотря на то, что с ним все Ок.
>поле в GROUP уточнил именем таблицы contest_cat
Уже лучше.
>прочитал по Вашей ссылке, рылся в мануале, но так и не смог понять как вытянуть остальные параметры. с чем связать contest.id_contest что бы вытянуть из таблицы и уже к этому привязывать остальные параметры?
Ограничения о которых мы сейчас говорим - это ограничения только для агрегатных запросов.
Обычные запросы таких ограничений не имеют.
Агрегатный запрос вернул Вам таблицу из двух столбиков.
Эту таблицу можно использовать как исходную таблицу в другом - сложном запросе.
Сложный запрос уже без GROUP BY и MAX() - агрегатным уже не будет. Таких ограничений иметь не будет. И в него можно натолкать любых нужных таблиц, из которых извлечь нужные поля.
Таблицы, конечно, нужно соединить. Это и проиллюстрировано по ссылке.
>возможно надо сделать к таблице contest вложеный запрос?
Не вложенный, а наоборот - объемлющий.
Вложенным будет агрегатный, уже написанный и отлаженный. | |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 21:20)
| | >Таблицы, конечно, нужно соединить. Это и проиллюстрировано по ссылке.
это до меня тоже дошло, не дошло как это сделать.
если агрегатный запрос будет вложеным, то как это организовать.
по Вашей ссылке я не пойму как к своему случаю это сделать?
получается что то типа
SELECT * FROM(агрегатный запрос) AS q
LEFT JION contest AS con ON q.quote = con.quote
|
по моему бред несу.... | |
|
|
|
|
|
|
|
для: Slo_Nik
(17.12.2009 в 21:39)
| | никакой не бред. Именно так. при этом таблица q - это результат работы вложенного (агрегатного, в данном случае) запроса.
только ON q.mquote = con.quote
Поскольку в агрегатном запросе у Вас алисасом столбик назван именно mquote | |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 22:33)
| | вот что получилось
SELECT `con`.`small` AS `small`,
`con`.`titleph` AS `title`,
`con`.`id_contest` AS `id_us`,
`con`.`quote` AS `quote`,
`con`.`id_contest_cat` AS `id_con`
FROM (SELECT `contest`.`id_contest_cat`,
MAX(`contest`.`quote`) AS `mquote`
FROM `contest`
LEFT JOIN `contest_cat` ON `contest`.`id_contest_cat` = `contest_cat`.`id_contest_cat`
GROUP BY `contest_cat`.`id_contest_cat`) AS `q`
LEFT JOIN `contest` AS `con` ON (`con`.`quote` = `q`.`mquote`)
LIMIT 3
|
получаю
small - 20091215154719_s.jpg
title - третий первого
id_us - 64
quote - 10
id_con - 15
small - 20091215102932_s.jpg
title - первый третьего
id_us - 56
quote - 2
id_con - 17
small - 20091215102639_s.jpg
title - первый второго
id_us - 55
quote - 2
id_con - 16
|
то что надо, но.................
если мне надо получить имя группы фотографий, то как я понял, мне надо дописать в запрос вот это
SELECT..............
`con2`name` AS `name`,
`con2`.`id_contest_cat` AS `id_con2`
FROM(................................)
LEFT JOIN..................................
LEFT JOIN `contest_cat` AS `con2` ON `con2`.`id_con2` = `q`.`id_contest_cat`
|
и получаю ошибку
mysql_fetch_assoc(): supplied argument is not.............
опять что то не так сделал?
исправил ошибку, применил в условии ON алиас поля, вот и полезла ошибка. | |
|
|
|
|
|
|
|
для: Slo_Nik
(17.12.2009 в 23:33)
| | >
>SELECT..............
>`con2`name` AS `name`,
>`con2`.`id_contest_cat` AS `id_con2`
>FROM(................................)
>LEFT JOIN..................................
>LEFT JOIN `contest_cat` AS `con2` ON `con2`.`id_con2` = `q`.`id_contest_cat`
>
|
>и получаю ошибку
>mysql_fetch_assoc(): supplied argument is not.............
>
>опять что то не так сделал?
>
>исправил ошибку, применил в условии ON алиас поля, вот и полезла ошибка.
`con2`name` AS `name`, - это что означает? По-моему в чистом виде синтаксическая ошибка.
не надо лепить LEFT JOIN внутрь агрегатного запроса - он и без того тяжел.
Ошибки следует исправлять не методом тыка, а читая диагностики.
>mysql_fetch_assoc(): supplied argument is not - это не диагностика.
Это сообщение о том , что после исполнения запроса, Вы не проверили результат, и не остановили скрипт сами, выведя диагностику из mysql_error(). | |
|
|
|
|
|
|
|
для: Trianon
(18.12.2009 в 08:31)
| | >Ошибки следует исправлять не методом тыка, а читая диагностики.
>mysql_fetch_assoc(): supplied argument is not - это не диагностика.
>Это сообщение о том , что после исполнения запроса, Вы не проверили результат, и не >остановили скрипт сами, выведя диагностику из mysql_error().
да, действительно у меня нет проверки результата запроса, вернее она ест, но после запроса
if(!$con) echo "......".mysql_error();
т.е. у меня нет or die();
>`con2`name` AS `name`, - это что означает? По-моему в чистом виде синтаксическая ошибка.
ошибка , но уже всё исправил, работает.
>не надо лепить LEFT JOIN внутрь агрегатного запроса - он и без того тяжел.
посмотрел внимательней на код, и LEFT JOIN убрал потому, что объеденения ни какого не происходит.
или я не прав?
и вопрос на будущее, по многотабличным запросам.
если надо применять в запросе агрегатные функции, то это запрос всегда делать вложенным или всё зависит от конкретной задачи? | |
|
|
|
|
|
|
|
для: Slo_Nik
(18.12.2009 в 20:25)
| | Вложенным надо делать запрос, если без этого, не нарушая правило неоднозначности (которое пятый раз я цитировать не буду) все поля не достать.
И Вы смотрите на запрос со стороны выхлопной трубы.
Не делать вложенным, а подсоединять нужные таблицы, путем обертывания снаружи.
Да-да-да! JOIN - это соединение, а не объединение.
касательно "нет die()"
Если Вы знаете, что запрос не прошел - зачем продолжать выполнение скрипта?
if(!$con) очевидно проверяет не запрос, а подключение к серверу. | |
|
|
|
|
|
|
|
для: Trianon
(17.12.2009 в 22:33)
| | Спасибо за помощь, всё работает:):):) | |
|
|
|
|
|
|
|
для: Slo_Nik
(18.12.2009 в 00:54)
| | Прийдётся вернуться к теме... поспешил с выводами.
Запрос работает, но есть одно "но".
схема осталась та же, три группы фотографий, надо вывести названия всех трёх групп и для каждой одно фото, с максимальным кол-вом голосов.
Всё так и выводится, но только тогда, когда для всех фото есть голоса, а если только создать группы, загрузить фото и кол-во голосов будет у всех фото "0", то запрос перестаёт нормально работать.
Начинает выводится две группы, для одной две позиции, для другой одна.
стоит только для одной фотографии в любой группе поставить хотя бы один голос, всё нармально работает...
я так понял, что проблема в этой части запроса
LEFT JOIN `contest` AS `con` ON (`con`.`quote` = `q`.`mquote`)
ORDER BY `con`.`quote` DESC
LIMIT 3
|
но ни как не могу сообразить, как отсортировать данные, если кол-во голосов у всех фото равны? | |
|
|
|
|
|
|
|
для: Slo_Nik
(22.12.2009 в 20:14)
| | Вы выводите для каждой группы одну фотографию с максимальным количеством голосов.
Допустим, у каждого из фото количество голосов "0". Как можно из кучи нолей выбрать максимум?
Вам в запросе нужно тогда поставить условие: если quote = 0, то или вообще не выбираем ничего, или выбираем фото с наибольшим(наименьшим) id. Вы что хотите вывести?
Приведите, пожалуйста, сам запрос, который у вас получился. | |
|
|
|
|
|
|
|
для: Лена
(22.12.2009 в 23:00)
| | сам запрос
SELECT `con`.`small` AS `small`,
`con`.`titleph` AS `title`,
`con`.`id_contest` AS `id_us`,
`con`.`id_contest_cat` AS `id_con_us`,
`con`.`quote` AS `quote`,
`cont`.`id_contest_cat` AS `id_cont`,
`cont`.`name` AS `name`
FROM (SELECT `contest`.`id_contest_cat`,
MAX(`contest`.`quote`) AS `mquote`
FROM `contest`
GROUP BY `contest`.`id_contest_cat`) AS `q`
LEFT JOIN `contest` AS `con` ON (`q`.`mquote` = `con`.`quote`)
LEFT JOIN `contest_cat` AS `cont` ON (`cont`.`id_contest_cat` = `con`.`id_contest_cat`)
ORDER BY `con`.`quote` DESC
LIMIT 3
|
этот запрос нормально работает, когда у всех фото или практически у всех есть голоса, т.е. quote не равно "0". тогда на главной странице выводится название для каждой группы и одно фото с максимальным quote для определённой группы.
если quote равно "0" у всех фото, тогда выводятся всего 2-е группы, для одной группы две позиции на странице, для другой одна.
получается, что если quote = "0", то надо будет сортировать по id сами фото,
если взять из запроса ту часть, где определяется максимальное quote, то даже с нулевым значением выводятся все группы. | |
|
|
|
|
|
|
|
для: Slo_Nik
(22.12.2009 в 23:09)
| | У вас по ссылке, которую привели выше, три группы, в каждой группе - фото с максимальным quote.
Я вам пыталась постом выше сказать: допустим, в каждой группе все фото с quote = "0". Еще понятнее. Группа 1. Самая левая. В ней, допустим, у вас три фото. У каждого фото quote = "0". И вы хотите из этих quote выбрать максимум. Это невозможно.
Вот есть у вас три вещи. Каждая из них стоит, допустим, 100 грн. Вы можете выбрать из этих трех вещей ту, которая больше всего стоит? У вас три цифры: 100, 100, 100 - можно из них максимум выбрать? Точно так же и с нолями.
У вас проблема не в LEFT JOIN `contest`, а в основной таблице, к которой соединяются столбцы из других таблиц.
Основная таблица SELECT `contest`.`id_contest_cat`, MAX(`contest`.`quote`)... не сможет из нолей выбрать максимум. А значит SQL вам подсунет какую-то ерунду. Мне так, по крайней мере кажется.
Поэтому вы должны решить: если у вас все quote = "0", вам или внутри этого запроса влепить условие исполнять его только, если quote != "0", или как-то по-другому... Подумаю, завтра на свежую голову скажу, уже спать хочется. | |
|
|
|
|
|
|
|
для: Лена
(23.12.2009 в 00:09)
| | смотрите, что получается.
проблема в том, что если quote равно "0", группы фотографий выводятся не по порядку, 1 , 2 , 3, а, например, 2 , 2 , 1. всего надо три группы вывести, да их и будет всего три.
если сделать простой запрос, как писал выше Trianon, то при подсчёте max quote,даже если quote = "0", группы выводятся как положено, 1 , 2 , 3.
вот эта часть запроса, через id_contest_cat связвываются две таблицы.
(SELECT `contest`.`id_contest_cat`,
MAX(`contest`.`quote`) AS `mquote`
FROM `contest`
GROUP BY `contest`.`id_contest_cat`) AS `q`
|
этот запрос нужен для того, что бы для каждой группы вывести одну фотографию с макс. quote.
делаю простой запрос для получения списка групп фотографий
SELECT
`contest_cat`.`id_contest_cat` AS `id_cont`,
`contest_cat`.`name` AS `name`
FROM `contest_cat`
|
получаю вывод всех трёх групп как и положено, 1 , 2 , 3, всё совпадает, имена групп соответствуют id групп.
теперь когда объеденяю эти два запроса(пример запроса выше), получается, что весь вывод ломается, группы выводятся не по порядку, а, например, 2 , 2 , 1
вот вопрос в том, как сохранить порядок вывода групп? | |
|
|
|
|
|
|
|
для: Slo_Nik
(23.12.2009 в 09:55)
| | Смотрите. Простой запрос,без максимума у меня выводит так:
17- Третий
15 - Первый
16 - Второй
Сложный запрос выводит категории так:
15 - Первый
17-Третий
16 - Второй.
А Вам как надо? | |
|
|
|
|
|
|
|
для: Лена
(23.12.2009 в 11:00)
| | мне без разницы как будет выводится, главное, что бы выводились группы, все три, 15,16,17, а какой последовательности не важно.
ещё главное условие, что бы для каждой группы, выводилось одна фотография с макс. quote,а если quote = 0, то порядок вывода групп не нарушался.
вот до этого я пока додуматься не могу. | |
|
|
|
|
|
|
|
для: Slo_Nik
(23.12.2009 в 11:13)
| | - | |
|
|
|
|
|
|
|
для: Trianon
(16.12.2009 в 13:30)
| | Не заметила. Из-за того, что автор алиасов для таблиц не использует, трудно читать. | |
|
|
|
|
|
|
|
для: Slo_Nik
(16.12.2009 в 12:57)
| | Много было в этой теме написано, много дельных советов, спасибо Trianon и Лена.
Для тех, кому интересно решение этой проблемы привожу запрос
"SELECT con.small AS small,
con.titleph AS title,
con.id_contest AS id_us,
con.id_contest_cat AS id_con_us,
con.quote AS mquote,
cont.id_contest_cat AS id_cont,
cont.name AS name
FROM(select contest.id_contest_cat,
max(contest.id_contest) as id_contest
FROM(SELECT contest.id_contest_cat,
MAX(contest.quote) AS mquote
FROM contest
GROUP BY contest.id_contest_cat) AS cq
LEFT JOIN contest ON (cq.mquote = contest.quote) and (cq.id_contest_cat=contest.id_contest_cat)
GROUP BY contest.id_contest_cat) as q
LEFT JOIN contest AS con ON (q.id_contest = con.id_contest)
LEFT JOIN contest_cat AS cont ON (cont.id_contest_cat = con.id_contest_cat)
ORDER BY con.quote DESC LIMIT 3"
|
Проверено, работает. | |
|
|
|
|
|
|
|
для: Slo_Nik
(20.01.2010 в 00:30)
| | На самом деле, весьма желательно эту тему переименовать в
"Как получить из таблицы строку с максимальным значением поля?"
Вопрос такой поднимается довольно часто, подводных камней у него масса.
А тут где-то как-то даже подход нарисовался... | |
|
|
|
|
|
|
|
для: Trianon
(20.01.2010 в 00:46)
| | Да я не против, пусть как хотят переименовывают, конечно если это принесёт пользу.
Но тогда надо отредактировать её, убрать лишнее....
Но я думаю, что предложеное название не совсем точно... | |
|
|
|
|