Помогите, SQL, двойная выборка

#16 4 января 2014 в 20:43
Вот не дает мне покоя данная задача )
Вроде бы и задача не сложная, с другой стороны просто не получается. Получилось со временной таблицей:
Как то так:
  1.  
  2. CREATE TABLE tmp SELECT plrid,MAX(totaluses) AS maxid FROM ps_plr_ids_name GROUP BY plrid;
  3. SELECT d.plrid, d.kills, d.deaths, n.name
  4. FROM ps_c_plr_data d
  5. LEFT JOIN ps_plr_ids_name n ON n.plrid = d.plrid
  6. INNER JOIN tmp t ON t.plrid = d.plrid AND t.maxid = n.totaluses
  7.  
Думаю, направление понятно. Додумайте сами. Подобная смоделированная задача у меня получилась.
Никогда не пользовался временными таблицами. Поэтому ничего не могу сказать об оптимальности запроса. Но запрос в цикле, если записей несколько сотен или тысяч, тоже не может быть оптимальным. В общем, пробуйте. Замените ваш запрос вот этим и вперед к отладке :=)
#17 4 января 2014 в 21:42
ByFly, если на словах, то наверное как то так:
1. основная выборка идет из второй таблицы, т.е. SELECT FROM table2 t2
2. к ней джойнится первая таблица по полю plrid, т.е. LEFT JOIN table1 t1 ON t1.plrid = t2.plrid
3. выполняем группировку GROUP BY t2.plrid
4. Выполняем сортировку ORDERED BY t2.totaluses DESC
#18 4 января 2014 в 22:14
Fuze, честно голову сломал. Но GROUP BY группирует по первому попавшемуся totaluses, но никак не по max(totaluses). WHERE обрабатывается до GROUP BY, но в WHERE нельзя использовать max(). А всё остальное(ORDER BY, HAVING) после GROUP BY.
ByFly, подправил запрос. Забыл добавить в выборку нужное вам поле name. Да и после запрос, наверно, нужно удалить временную таблицу.
#19 4 января 2014 в 22:44

Fuze, честно голову сломал. Но GROUP BY группирует по первому попавшемуся totaluses, но никак не по max(totaluses). WHERE обрабатывается до GROUP BY, но в WHERE нельзя использовать max(). А всё остальное(ORDER BY, HAVING) после GROUP BY.

Марат

Вот и я не могу понять как можно так сделать xDDD
Но америкосы это как-то сделали...

Марат, словами трудно описать то, что я хочу сделать, на самом деле в мыслях представление простое и понятное, но вот описать чё-то не могу.
По поводу временной таблице что вы написали, это не то.
У меня имеется игровой скрипт, короче в них структура такая БД.
Но я в нём не могу понять как он вообще работает и где все эти переменные и запросы находятся xD
#20 4 января 2014 в 22:49
Марат, точно)
ну тогда что то вроде этого
SELECT plrid, MAX(totaluses) GROUP BY plrid
#21 4 января 2014 в 22:54
Fuze, основная выборка идёт из первой таблице по kills, потом к этой выборки добавляется name из второй таблице по выборке totaluses где plrid из первой выборки = plrid из второй, как-то так xD
#22 4 января 2014 в 22:55
Подождите, сейчас напишу простенькую задачу на понятном языке.
#23 4 января 2014 в 23:04
ByFly, так вроде всё правильно понял вас. Основная выборка из первой таблицы. Присоединяем строку, содержащую t2.name, из второй таблицы по условию t2.plrid = t1.plrid. Причем во второй таблице строк, соответсвующих условию может быть несколько. Нужно выбрать ту, у которой максимальное значение t2.totaluses. Если так, то приведенный мной запрос должен работать. Скажем так, один из вариантов. Возможно более изящно можно решить посредством пхп. Но мне интереснее стало сделать это посредством мускул.
#24 4 января 2014 в 23:06
Есть двацад продавцов, которые торгуют яблоками.
Каждый продавец имеет свой рейтинг.
1) Вывести список продавцов по рейтингу.
Далее у каждого продавца разные виды яблок.
2) Добавить в список продавцов тот вид яблок, который наибольше был продан.

Продавец Рейтинг
Вася — 100
Миша — 70
Витя — 50
Даша — 30
Лера — 10

У Вася продано: 20 штук антоновки, 40 штук ранеток, 15 штук ранних яблок.
У Миши продано: 15 штук антоновки, 7 штук ранеток.
У Вити продано: 19 штук антоновки, 12 штук ранеток, 5 штук ранних яблок.
У Даши продано: 30 штук антоновки, 15 штук ранеток.
У леры продано: 25 штук антоновки, 17 штук ранеток, 6 ранних яблок.

Вывести в массив 3 лучших продавца типа: Имя, Рейтинг, Название наибольше проданного вида яблок
Вася 100 Ранетки
Миша 70 Антоновки
Витя 50 Антоновки
#25 4 января 2014 в 23:07
Марат, да, вы правильно поняли :)
Какой именно запрос правильный?)
#26 4 января 2014 в 23:14

Какой именно запрос правильный?)

ByFly
В посте 16. Да и под спойлером в посте 9 тоже должно работать. Только там нужно внести изменение из поста №15 и плюс ещё в запросе нужно установить LIMIT 10 на LIMIT 1
То есть заменить строки 21-30 кода из под спойлера на:
  1.  
  2. //здесь сам запрос
  3. $query_2 = "SELECT name FROM ps_plr_ids_name WHERE plrid={$plrid} ORDER BY totaluses DESC
  4. LIMIT 1";
  5. $res_2 = mysql_query($query_2);
  6. //далее обрабатываем полученный массив
  7. if(num_rows($res_2){
  8. $row_2 = mysql_fetch_assoc($res_2)
  9. echo $row_2['name'];
  10. }
  11.  
#27 4 января 2014 в 23:20
Марат, я проверял ваш способ, почему-то ничего не работает вообще, то есть не отображается...

Вот полностью код, который у меня получился:
  1. <?
  2. define("PSYCHOSTATS_PAGE", true);
  3. include(dirname(__FILE__) . "/includes/common.php");
  4.  
  5. $query = "SELECT plrid, kills, deaths FROM ps_c_plr_data ORDER BY kills DESC
  6. LIMIT 10";
  7. $res = mysql_query($query);
  8.  
  9. echo'
  10. <table class="table1" width="550" align="center" bgcolor="#F4F4F4">
  11. <tr bgcolor="#8C8C8C">
  12. <th width="50" align="center">#</th>
  13. <th width="300" align="center">Игрок</th>
  14. <th width="100" align="center">Статистика</th>
  15. </tr>
  16. ';
  17.  
  18. $i=1;
  19. while($row = mysql_fetch_array($res))
  20. {
  21. $plrid = $row['plrid'];
  22. $kills = $row['kills'];
  23. $deaths = $row['deaths'];
  24.  
  25. echo'<tr><td>'.$i;
  26. echo'</td><td>';
  27. //здесь сам запрос
  28. $query_2 = "SELECT name FROM ps_plr_ids_name WHERE plrid={$plrid} ORDER BY totaluses DESC
  29. LIMIT 10";
  30. $res_2 = mysql_query($query_2);
  31. //далее обрабатываем полученный массив
  32. if(mysql_num_rows($res_2){
  33. while($row_2 = mysql_fetch_array($res_2)){
  34. echo $row_2['name'].'<br>';
  35. }
  36. }
  37. echo'</td><td align="center">';
  38. echo $kills;
  39. echo'-';
  40. echo $deaths;
  41. echo'</td></tr>';
  42. $i++;
  43. }
  44.  
  45. echo'</table>';
  46. ?>
#28 4 января 2014 в 23:31
ByFly, ну если не работает, значит должна быть ошибка. Изучаем логи или пробуем вывести ошибки на экран(что удобнее при отладке). Если явных ошибок нет, тогда выводим переменные и смотрим значения. var_dump(), print_r() вам в помощь. Что получаем из базы после выполнения запроса и.т.д...
Строки из под вашего спойлера 27-36 попробуйте заменить на мои из поста 26
#29 4 января 2014 в 23:51
Марат, не могу понять… пустая белая страница и всё… и даже не отображает данные var_dump() и print_r()
#30 4 января 2014 в 23:54
Попробуйте заменить в самом начале <? на <?php
Вы не можете отвечать в этой теме.
Войдите или зарегистрируйтесь, чтобы писать на форуме.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.