Есть таблица товаров с привязкой к пользователю по tov_owner Код (Text): CREATE TABLE IF NOT EXISTS `tovar` ( `tov_id` int(10) NOT NULL AUTO_INCREMENT, `tov_cat` int(4) NOT NULL, `tov_nazv` varchar(100) COLLATE utf8_bin NOT NULL, `tov_opis` text COLLATE utf8_bin NOT NULL, `tov_owner` int(10) DEFAULT '0', PRIMARY KEY (`tov_id`) ) ; Есть таблица пользователей: Код (Text): CREATE TABLE IF NOT EXISTS `users` ( `user_id` int(11) NOT NULL AUTO_INCREMENT, `user_login` varchar(50) COLLATE utf8_bin NOT NULL, `user_pass` varchar(32) COLLATE utf8_bin NOT NULL, `user_sol` char(3) COLLATE utf8_bin NOT NULL, PRIMARY KEY (`user_id`) ) ; и есть таблица отзывов, которые выставляются для пользователя Код (Text): CREATE TABLE IF NOT EXISTS `feedbacks` ( `feedback_id` int(2) NOT NULL AUTO_INCREMENT, `feedback_nazv` varchar(150) COLLATE utf8_bin NOT NULL, `feedback_text` text COLLATE utf8_bin NOT NULL, `feedback_owner` int(10) DEFAULT '0', `feedback_receiver` int(10) DEFAULT '0', `time` datetime NOT NULL, `feedback_rate` int(2) NOT NULL, `active` int(2) NOT NULL DEFAULT '0', PRIMARY KEY (`feedback_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=10 ; Задача: нужно найти все товары из tovar которые бы сортировались бы сумме feedback_rate пользователя владельца товара... Если честно я даже теряюсь с какой стороны подойти, это нужно два JOIN делать или как?
ну чтоб три таблицы объединить нужно два джойна да. но раз есть аунер товара то зачем дергать таблицу юзеров? ради никнейма?
А как сделать два джойна? Можете на примере тех таблиц что я привел показать запрос? Буду благодарен.
референс мануал научиться уже наконец читать select fields from table join anothertableone on joinstatementone join anothertabletwo on joinstatementtwo join anothertablen on joinstatementn where statement etc... вместо того чтоб почитать основы реляционных баз данных и понять как вообще данные разными вариантами джойна связываются мы сидим на форуме и ждем когда за нас напишут три строки кода...
поддерживаю предыдущего оратора сумсум, тебя ведь уже спрашивали почему ты используешь COLLATE utf8_bin ? так почему?
Код (Text): SELECT t1.*, SUM(t2.feedback_rate) AS sum_rating FROM tovar t1 LEFT JOIN feedbacks t2 ON t1.tov_owner = t2.feedback_receiver GROUP BY t2.feedback_receiver ORDER BY sum_rating DESC
нельзя в одном запросе делать SELECT * и GROUP BY Добавлено спустя 1 минуту 51 секунду: и еще, хоть автор и сказал "сумма фидбека", это какая-то бессмысленная величина. наверное все-таки среднее значение фидбека.
А почему бы и нет? Собственно данные в УТФ-8 а как еще их хранить? Добавлено спустя 9 минут 49 секунд: Спасибо за пример. Но теперь возникла проблема. Мне нужно получать в поиске товары и сортировать их по tov_nazv но те товары что с большим рейтингом в отзывах выводить вверху. В вашем примере оно выводит только те товары владельцы которых имеют отзывы, а нужно что бы выводило в том числе и товары без отзывов.
понятно. ты просто не в курсе что такое коллейшн (настройка сравнения и сортировки). путаешь с набором символов. и к тому же необязательно расписывать кодировку для каждой колонки, достаточно один раз на таблицу. DEFAULT CHARSET=utf8, задаст кодировку utf8 и коллейшн по умолчанию равный utf8_general_ci — это всех устраивает обычно ))) если ты не в курсе в чем разница между *ci и *bin, то и нет причины явно указывать что-то особенное, ящитаю. но я не настаиваю, конечно, дело хозяйское.
Я так и делал создавал кодировку для таблицы, просто когда экспорт таблицы делаешь то пхпМайАдмин сам вставляет COLLATE utf8_bin так же как и CREATE TABLE IF NOT EXISTS
Помоги с вопросом как в этом примере Код (Text): SELECT t1.*, SUM(t2.feedback_rate) AS sum_rating FROM tovar t1 LEFT JOIN feedbacks t2 ON t1.tov_owner = t2.feedback_receiver ORDER BY sum_rating DESC сделать что бы выводились не только те товары у владельцев которых есть отзывы а все, в том числе и у которых нет отзывов
потому что результат непредсказуем. группировка требует строгости в наборе полей на выходе. см. очень близкую тему где-то такие финты просто запрещены и это правильно!!! вот пруф из офф. документации. Добавлено спустя 55 секунд: @sumsum, чтобы написать запрос, надо попытаться сформулировать его по русски и тупо перевести на английский. будет очень похоже на SQL ))) я не понял что именно ты хочешь вывести. попробуй сформулировать без вывертов вроде "но не те которые, а наоборот", а простым языком как для слабоумных: "выбрать такие-то поля оттуда-то, при том что такие-то поля равны тому-то" — примерно так
Код (Text): Вывести все товары из tovar отсортировать по tov_nazv и SUM(t2.feedback_rate) Код (Text): SELECT * FROM tovar (еще надо как то сджоинить feedbacks) ORDER BY tov_nazv, SUM(t2.feedback_rate) Все что я смог придумать Помоги Добавлено спустя 3 минуты 51 секунду: Мне нужно вывести все товары и отсортировать по tov_nazv НО те товары владельцы, которых имеют лучше отзывы в feedbacks должны выводиться выше скажем находим в поиске два одинаковых товара ложка (владелец Саша) ложка (владелец Маша) у них все одинаковое и цена и название но у Маши рейтинг 20 а у саши 5 (потому что он мудак )))) нужно Машин товар в поиске вывести первым а Сашин вторым Добавлено спустя 2 минуты 8 секунд: Добавлю еще для наглядности скажем есть еще один товар ложка (владелец Петя) но его вообще никто никак не оценил (его нет в таблице feedbacks). в выдаче должно идти в такой последовательности: ложка (владелец Маша) ложка (владелец Саша) ложка (владелец Петя)
сначала надо определиться с понятием "лучшие отзывы в feedbacks". подкрадываемся издалека: Код (Text): SELECT `feedback_receiver` AS `user_id`, AVG(`feedback_rate`) AS `avg_rate` FROM `feedbacks` GROUP BY `feedback_receiver` ORDER BY 2 DESC правильно? AVG(fld) означает "среднее значение в группе", то есть сумма колонки, поделить на количество строк ORDER BY 2 означает "сортировать по второй колонке по убыванию" если этот запрос верно отражает "лучшие рейтинги", дальше давай сам — используй этот запрос (без order by) как ПОДзапрос, джойни его с чем надо и сортируй результат
А почему не SUM? Хотя по большому счету в данном случае это вообще не принципиально, в результате по логике будет то же самое Ок, а как это все увязать к товарам? что бы выводились товары как с отзывами так и без отзывов?
у тебя же пользователи к отзывам относятся как один-ко-многим. как это "то же самое"! вот у тебя допустим оценка по пятибальной шкале. одного перца оценили трое: на 3, на 4 и на 5. сумма будет 12. ты когда-нибудь видел оценку 12 по пятибальной шкале? а средняя оценка 4. короче, дальше сам. у тебя есть всё для решения.
У меня трехбальная шкала: -1 негативный 0 нейтральный 1 полодительный Та отзывы то ладно меня интересует главный вопрос. По сортировке я как нибудь бы разобрался А вот как сделать что бы выводились и товары с отзывами и без - вот тут загвоздка
ок, еще одна попытка. вот твоя формулировка задачи: то, что там не sum, а avg должно быть, я просто ставлю тебя в известность, возражалка у тебя еще не выросла. надо вывести данные из tovar и единственно чего там не хватает для твоей хотелки — это поля с рейтингом хозяина. решаем это через "левое объединение" товаров с тем подзапросом, который я выше для тебя сделал. левое, потому что в общем случае фидбек может быть не у всех пользователей, поэтому объединение придется сделать открытым. сортировку тебе хочется по двум признакам, тут нет никаких хитростей кроме приоритетов. что левее в списке order by, то оказывается более весомым. дальше жевать уже некуда. бери и глотай )))
Что то я запутался... Делаю простую выборку из таблицы товаров: Код (Text): SELECT * FROM `tovar` получаю количество товаров Код (Text): Showing rows 0 - 29 (60,376 total, Query took 0.0109 sec) Дальше делаю выборку с лефт джоином Код (Text): SELECT T.* FROM `tovar` AS T LEFT JOIN feedbacks AS F ON T.tov_owner=F.feedback_receiver получаю количество товаров Код (Text): Showing rows 0 - 29 (67,047 total, Query took 0.0050 sec) Правильно ли я понимаю что разница 67047-60378=6671 это то что прибавляется к таблице товаров то что нашло с отзывами? НО если я отдельно этот поиск сделаю то есть через INNER JOIN Код (Text): SELECT T.* FROM `tovar` AS T INNER JOIN feedbacks AS F ON T.tov_owner=F.feedback_receiver то получу результат поиска Код (Text): Showing rows 0 - 29 (7,624 total, Query took 0.1308 sec) то есть на 7624-6671=953 товара больше ... не могу понять откуда взялись эти 953 товара? Добавлено спустя 2 минуты 19 секунд: То есть разве не так должно быть Лефт Джоин = товар + Иннер Джоин?
Вроде решил таки вопрос, всем спасибо за помощь Код (Text): SELECT T.*,F.avg_rate AS avg_rate FROM `tovar` AS T LEFT JOIN ( SELECT `feedback_receiver` AS `user_id`, AVG(`feedback_rate`) AS `avg_rate` FROM `feedbacks` AS F GROUP BY `feedback_receiver` ) AS F ON T.tov_owner=F.user_id ORDER BY F.avg_rate DESC