Сергей Добросклонов
|
|
« : 16-06-2011 12:23 » |
|
Имеются таблицы: users,videos,photos,articles. Необходимо выбрать информацию о всех пользователях, а так же подсчитать рейтинг каждого по выложенным им материалам, а именно: по видео, фото и статьям. Таблицы videos,photos,articles содержат id,id_who (это поле связующее с id в таблице users),voting(сколько раз голосовали),ballet (сумма всех оценок). Для начала я сделал так: $join = mysql_query("SELECT users.id,users.niсk,users.photo,SUM(videos.ballet)/SUM(videos.voting) AS rat_vid, SUM(photos.ballet)/SUM(photos.voting) AS rat_ph, SUM(articles.ballet)/SUM(articles.voting) AS rat_art FROM users LEFT JOIN videos ON videos.id_who=users.id LEFT JOIN photos ON photos.id_who=users.id LEFT JOIN articles ON articles.id_who=users.id GROUP BY users.id",$db);
if ($join && mysql_num_rows($join)>0) { $join_res = mysql_fetch_array($join); do { echo $join_res['niсk']; echo "<img src='".$join_res['photo']."'><br>"; echo "Рейтинг по видео: ".$join_res['rat_vid']."<br>"; echo "Рейтинг по фото: ".$join_res['rat_ph']."<br>"; echo "Рейтинг по статьям: ".$join_res['rat_art']."<br>"; } while($join_res = mysql_fetch_array($join)); }
Всё отлично работает, считает корректно. Затем сделал так: $join = mysql_query("SELECT users.id,users.niсk,users.photo,((SUM(videos.ballet)+SUM(photos.ballet)+SUM(articles.ballet))/(SUM(videos.voting)+SUM(photos.voting)+SUM(articles.voting))) AS rating FROM users LEFT JOIN videos ON videos.id_who=users.id LEFT JOIN photos ON photos.id_who=users.id LEFT JOIN articles ON articles.id_who=users.id GROUP BY users.id",$db);
if ($join && mysql_num_rows($join)>0) { $join_res = mysql_fetch_array($join); do { echo $join_res['niсk']; echo "<img src='".$join_res['photo']."'><br>"; echo "по рассказам: ".$join_res['rating']."<br>"; } while($join_res = mysql_fetch_array($join)); }
И получил нечто странное: показывается рейтинг только первого пользователя и то он не соответствует реальным данным, а у других вообще пустота... Помогите, пожалуйста, составить верный запрос, очень устал от этой проблемы.
|
|
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #1 : 16-06-2011 16:04 » |
|
На первый взгляд вроде все ок... Попробуй может вместо ((SUM(videos.ballet)+SUM(photos.ballet)+SUM(articles.ballet))/(SUM(videos.voting)+SUM(photos.voting)+SUM(articles.voting))) написать ((SUM(videos.ballet+photos.ballet+articles.ballet))/(SUM(videos.voting+photos.voting+articles.voting)))
|
|
|
Записан
|
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #2 : 16-06-2011 17:25 » |
|
GROUP BY users.id, users.nick, users.photo вот пример: SQL> WITH users AS ( 2 SELECT 1 id, 'nick1' nick, 'photo1' photo FROM dual UNION ALL 3 SELECT 2 id, 'nick2' nick, 'photo2' photo FROM dual), 4 videos AS ( 5 SELECT 1 id, 1 id_who , 1 ballet, 1 voting FROM dual UNION ALL 6 SELECT 2 id, 2 id_who , 2 ballet, 1 voting FROM dual), 7 photos AS ( 8 SELECT 1 id, 1 id_who , 1 ballet, 1 voting FROM dual UNION ALL 9 SELECT 2 id, 2 id_who , 4 ballet, 1 voting FROM dual), 10 articles AS ( 11 SELECT 1 id, 1 id_who , 1 ballet, 1 voting FROM dual UNION ALL 12 SELECT 2 id, 2 id_who , 5 ballet, 1 voting FROM dual) 13 SELECT users.id, 14 users.nick, 15 users.photo, 16 ((SUM(videos.ballet) + SUM(photos.ballet) + SUM(articles.ballet)) / 17 (SUM(videos.voting) + SUM(photos.voting) + SUM(articles.voting))) AS rating 18 FROM users 19 LEFT JOIN videos ON videos.id_who = users.id 20 LEFT JOIN photos ON photos.id_who = users.id 21 LEFT JOIN articles ON articles.id_who = users.id 22 GROUP BY users.id, users.nick, users.photo 23 /
ID NICK PHOTO RATING ---------- ----- ------ ---------- 2 nick2 photo2 3,66666666 1 nick1 photo1 1 Это пример из Oracle, странно, что MySQL даёт делать группировку только по одному полю - Оракл таких вольностей не позволяет
|
|
« Последнее редактирование: 16-06-2011 17:28 от PooH »
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
RXL
|
|
« Ответ #3 : 16-06-2011 17:57 » |
|
Позволяет, но выдача негруппируемых полей непредсказуема. По этому делать этого не следует. Зато MySQL позволяет ссылаться в GROUP BY, HAVING и ORDER BY на алиасы - скрыто производит перезапись запроса с разворачиванием алиасов. Увидеть это можно посредством "EXPLAIN EXTENDED <запрос>" c последующим просмотром сообщений: SHOW WARNINGS.
Все запросы надо отлаживать перед внедрением в программу. И внимательно читать предупреждения.
|
|
« Последнее редактирование: 16-06-2011 18:03 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Kivals
|
|
« Ответ #4 : 16-06-2011 18:01 » |
|
Так тут суть не в правильности заполнения полей, а в неверном количестве записей Еще не понятно как отработает СУМ() и "+" в случае NULL аргументов...
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #5 : 16-06-2011 18:07 » |
|
Если под SUM() попадают только поля с NULL, то результат - NULL. Если есть хоть одно значение, то NULL эквивалентно нулю. Т.е. результат опять же не предсказуем.
Сперва надо бы увидеть скрипт таблицы: SHOW CREATE TABLE tablename.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #6 : 16-06-2011 18:16 » |
|
"Т.е. результат опять же не предсказуем." Ну почему же? 0 или NULL, разве нет?
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
RXL
|
|
« Ответ #7 : 16-06-2011 18:18 » |
|
Почему я говорю, что непредсказуем: в одном запросе будет NULL, в другом - число. А тут еще и формула. Интересно, есть ли исключение "делением на NULL"...
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #8 : 16-06-2011 18:18 » |
|
"Зато MySQL позволяет" И что это дает?
Добавлено через 46 секунд: "в одном запросе будет NULL, в другом - число" Ну так если есть данные то, будет число, нет данных - будет NULL. Так ведь?
|
|
« Последнее редактирование: 16-06-2011 18:19 от PooH »
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
Kivals
|
|
« Ответ #9 : 16-06-2011 18:26 » |
|
PooH, Да, но поскольку результат SUM() у нас операнд математической операции - то какой результат будет: NULL / Число Число / NULL NULL / NULL ?
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #10 : 16-06-2011 18:27 » |
|
надо просто убрать left join
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
RXL
|
|
« Ответ #11 : 16-06-2011 18:27 » |
|
"Зато MySQL позволяет" И что это дает?
Упрощение записи. Это я софтопил. (А еще это не позволяет Oracle.)
|
|
« Последнее редактирование: 16-06-2011 18:33 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Kivals
|
|
« Ответ #12 : 16-06-2011 18:30 » |
|
надо просто убрать left join
? И получить декартово произведение 4х таблиц?
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #13 : 16-06-2011 18:30 » |
|
PooH[/b], не.... Например: (SUM(videos.ballet)+SUM(photos.ballet)+SUM(articles.ballet))/(SUM(videos.voting)+SUM(photos.voting)+SUM(articles.voting)) Если строк таблицы videos будет ноль, то результат всего выражения - NULL. В такиз случаях я делаю IFNULL(SUM(field), 0).
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Sla
|
|
« Ответ #14 : 16-06-2011 18:36 » |
|
Kivals, нет использовать inner join
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #15 : 16-06-2011 18:44 » |
|
ааа, понял, ну значит так же как в Ораклине я просто не правильно понял твою фразу "Если есть хоть одно значение, то NULL эквивалентно нулю."
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #16 : 16-06-2011 18:45 » |
|
зачем тут какие-то джоины? вон я привел корректный пример выше. с NULL бороться просто при помощи IFNULL.
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
Kivals
|
|
« Ответ #17 : 16-06-2011 18:46 » |
|
Sla, тогда мы потеряем записи, для которых нет эквивалентов хотя бы в одной из таблиц videos,photos,articles Я все-таки больше склоняюсь к варианту RXL: использовать IFNULL()
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #18 : 16-06-2011 18:47 » |
|
ааа, понял, ну значит так же как в Ораклине я просто не правильно понял твою фразу "Если есть хоть одно значение, то NULL эквивалентно нулю." Это для случая: id val 1 1 2 2 3 3 4 NULL SUM(val) даст 6, а при WHERE id = 4 даст NULL.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Kivals
|
|
« Ответ #19 : 16-06-2011 18:49 » |
|
PooH, так у тебя тоже LEFT JOIN
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #20 : 16-06-2011 18:50 » |
|
И надо учесть деление на ноль - оно тоже дает NULL.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #21 : 16-06-2011 18:51 » |
|
ну вот я и говорю, что все с джоинами тут нормально, никаких других не надо Добавлено через 43 секунды:RXL, тут по логике не может быть число/null, только null/null
|
|
« Последнее редактирование: 16-06-2011 18:51 от PooH »
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
RXL
|
|
« Ответ #22 : 16-06-2011 18:53 » |
|
Может быть и "0/0". В обеих случаях всю формулу тоже стоит обернуть IFNULL().
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Kivals
|
|
« Ответ #23 : 16-06-2011 18:55 » |
|
Offtopic: Развели мы тут дискуссию, а автора нет
|
|
|
Записан
|
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #24 : 16-06-2011 19:01 » |
|
да автору сразу дали ответ, а остальное разглагольствования на тему тюнинга и "предпросмотра" граблей - очень полезные вещи, кстати. Автор думаю будет не в обиде
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
Сергей Добросклонов
|
|
« Ответ #25 : 17-06-2011 08:46 » |
|
Автор тут. Просто у автора интернет 64 кбит/сек, поэтому часто не захожу Всем спасибо, что так живо отреагировали! Как испробую ваши советы отпишусь получилось или нет Добавлено через 2 часа, 10 минут и 6 секунд:Вот это: GROUP BY users.id, users.nick, users.photo
ничего не дало, но я оставил на всякий случай. Это: В такиз случаях я делаю IFNULL(SUM(field), 0).
и это: В обеих случаях всю формулу тоже стоит обернуть IFNULL().
сильно помогло. Теперь если у кого-то из пользователей нет записей в одной из таблиц, это не превращает его рейтинг в 0, а у кого нет вообще никаких файлов рейтинг 0 вместо пустоты. Но есть проблема... Пересчитал все записи в таблицах (благо их там мало) и вот что получается: Пользователь 1 Видео: 5 голосов - 24 балла Фото: 4 голоса - 18 баллов Статьи: 1 голос - 2 балла Итого: (24+18+2)/(5+4+1) = 4.4 Результат запроса: 3.6154 Пользователь 2 0 - 0 4 - 16 0 - 0 Итого: 16/4 = 4 Результат запроса: 3.6667 Пользователь 3 4 - 19 0 - 0 3 - 13 Итого: 4.5714 И результат тоже 4.5714 !!! Почему так понять не могу. Одну вещь вижу: у третьего пользователя нет фото и считается правильно, у других фотографии есть и какой-то косяк. Но, полагаю, что это совпадение, хотя, возможно, странная работа left join'а.
|
|
« Последнее редактирование: 17-06-2011 10:56 от Барин »
|
Записан
|
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #26 : 17-06-2011 12:51 » |
|
давай скрипты для создания и заполнения таблиц. Вон вверху пример, все считается корректно надо смотреть на твои данные и твой запрос.
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
Сергей Добросклонов
|
|
« Ответ #27 : 17-06-2011 14:13 » |
|
Вот скрипт и база. Я скопировал нужные таблицы из своей старой БД в новую и написал скрипт на отдельной странице с подключением к новой базе. Теперь у первого пользователя рейтинг 4.3333 (вместо 4.4, которых должно быть и вместо 3.6154, которых выводит из старой базы с аналогичными данными).... Не пойму как так может быть...
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #28 : 17-06-2011 14:43 » |
|
"Зато MySQL позволяет" И что это дает?
Упрощение записи. Это я софтопил. (А еще это не позволяет Oracle.) Дело в том что, чтобы пользоваться алиасами в group by нужно быть уверенным в том что алиас объявлен до того когда он используется. В пределах одного запроса этого нельзя сделать, поэтому если необходимо использовать алиасы в группировке, можно воспользоваться подзапросом. SELECT COUNT(*), (SELECT * FROM....) AS "alias" FROM TABLE GROUP BY (SELECT * FROM....) Как это можно переписать с ипользованием алиасов. SELECT COUNT, alias FROM (SELECT COUNT(*) AS "count", (SELECT * FROM....) AS "alias" FROM TABLE) GROUP BY "alias" Но еслиговорить о упрощении записи, то лучше оставлять без подзапросов и не использовать алиасов в группировке. Это касаемо Oracle.
|
|
« Последнее редактирование: 17-06-2011 14:49 от McZim »
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #29 : 17-06-2011 15:00 » |
|
какая интересная архитектура лефт джоинами просто с таблицами тут не обойтись... ща раскапаем Добавлено через 42 минуты и 4 секунды:ну собственно вот: SELECT u.id, u.nick, u.photo, v.b, p.b, a.b, v.v, p.v, a.v, ifnull((ifnull(v.b, 0) + ifnull(p.b, 0) + ifnull(a.b, 0)) / (ifnull(v.v, 0) + ifnull(p.v, 0) + ifnull(a.v, 0)), 0) FROM users AS u LEFT JOIN (SELECT id_who, SUM(ballet) b, SUM(voting) v FROM videos t GROUP BY id_who) AS v ON v.id_who = u.id LEFT JOIN (SELECT id_who, SUM(ballet) b, SUM(voting) v FROM photos t GROUP BY id_who) AS p ON p.id_who = u.id LEFT JOIN (SELECT id_who, SUM(ballet) b, SUM(voting) v FROM articles t GROUP BY id_who) AS a ON a.id_who = u.id получаем id nick photo b b b v v v rating 1 Пользователь 1 1.jpg 24 14 7 5 3 2 4.50 2 Пользователь Х 1.jpg NULL NULL NULL NULL NULL NULL 0.00 3 Пользователь 2 1.jpg NULL 11 0 NULL 3 0 3.67 44 Пользователь 3 1.jpg 19 NULL NULL 4 NULL NULL 4.75
|
|
« Последнее редактирование: 17-06-2011 15:45 от PooH »
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
RXL
|
|
« Ответ #30 : 17-06-2011 18:20 » |
|
Пользователь 1 Видео: 5 голосов - 24 балла Фото: 4 голоса - 18 баллов Статьи: 1 голос - 2 балла Итого: (24+18+2)/(5+4+1) = 4.4 Результат запроса: 3.6154
Вижу иное: mysql> SELECT id, (vb + pb + ab) / (vv + pv + av), vb, pb, ab, vv, pv, av -> FROM ( -> SELECT users.id, -> IFNULL(SUM(videos.ballet),0) vb, -> IFNULL(SUM(photos.ballet),0) pb, -> IFNULL(SUM(articles.ballet),0) ab, -> IFNULL(SUM(videos.voting),0) vv, -> IFNULL(SUM(photos.voting),0) pv, -> IFNULL(SUM(articles.voting),0) av -> FROM users -> LEFT JOIN videos ON videos.id_who = users.id -> LEFT JOIN photos ON photos.id_who = users.id -> LEFT JOIN articles ON articles.id_who = users.id -> GROUP BY users.id -> ) t; +----+---------------------------------+-----+------+-----+-----+-----+-----+ | id | (vb + pb + ab) / (vv + pv + av) | vb | pb | ab | vv | pv | av | +----+---------------------------------+-----+------+-----+-----+-----+-----+ | 1 | 4.3333 | 864 | 1764 | 882 | 180 | 378 | 252 | | 2 | NULL | 0 | 0 | 0 | 0 | 0 | 0 | | 3 | 3.6667 | 0 | 33 | 0 | 0 | 9 | 0 | | 44 | 4.7500 | 19 | 0 | 0 | 4 | 0 | 0 | +----+---------------------------------+-----+------+-----+-----+-----+-----+ 4 rows in set (0.01 sec)
Добавлено через 8 минут и 48 секунд:Посмотри на это и догадайся, почему такое происходит: mysql> SELECT users.id, videos.id, photos.id, articles.id -> FROM users -> LEFT JOIN videos ON videos.id_who = users.id -> LEFT JOIN photos ON photos.id_who = users.id -> LEFT JOIN articles ON articles.id_who = users.id -> WHERE users.id = 1; +----+------+------+------+ | id | id | id | id | +----+------+------+------+ | 1 | 1 | 1 | 1 | | 1 | 1 | 1 | 2 | | 1 | 1 | 1 | 3 | | 1 | 1 | 1 | 7 | | 1 | 1 | 1 | 9 | | 1 | 1 | 1 | 8 | | 1 | 1 | 6 | 1 | | 1 | 1 | 6 | 2 | | 1 | 1 | 6 | 3 | | 1 | 1 | 6 | 7 | | 1 | 1 | 6 | 9 | | 1 | 1 | 6 | 8 | | 1 | 1 | 9 | 1 | | 1 | 1 | 9 | 2 | | 1 | 1 | 9 | 3 | | 1 | 1 | 9 | 7 | | 1 | 1 | 9 | 9 | | 1 | 1 | 9 | 8 | | 1 | 1 | 11 | 1 | | 1 | 1 | 11 | 2 | | 1 | 1 | 11 | 3 | | 1 | 1 | 11 | 7 | | 1 | 1 | 11 | 9 | | 1 | 1 | 11 | 8 | | 1 | 1 | 12 | 1 | | 1 | 1 | 12 | 2 | | 1 | 1 | 12 | 3 | | 1 | 1 | 12 | 7 | | 1 | 1 | 12 | 9 | | 1 | 1 | 12 | 8 | | 1 | 1 | 13 | 1 | | 1 | 1 | 13 | 2 | | 1 | 1 | 13 | 3 | | 1 | 1 | 13 | 7 | | 1 | 1 | 13 | 9 | | 1 | 1 | 13 | 8 | | 1 | 4 | 1 | 1 | | 1 | 4 | 1 | 2 | | 1 | 4 | 1 | 3 | | 1 | 4 | 1 | 7 | | 1 | 4 | 1 | 9 | | 1 | 4 | 1 | 8 | | 1 | 4 | 6 | 1 | | 1 | 4 | 6 | 2 | | 1 | 4 | 6 | 3 | | 1 | 4 | 6 | 7 | | 1 | 4 | 6 | 9 | | 1 | 4 | 6 | 8 | | 1 | 4 | 9 | 1 | | 1 | 4 | 9 | 2 | | 1 | 4 | 9 | 3 | | 1 | 4 | 9 | 7 | | 1 | 4 | 9 | 9 | | 1 | 4 | 9 | 8 | | 1 | 4 | 11 | 1 | | 1 | 4 | 11 | 2 | | 1 | 4 | 11 | 3 | | 1 | 4 | 11 | 7 | | 1 | 4 | 11 | 9 | | 1 | 4 | 11 | 8 | | 1 | 4 | 12 | 1 | | 1 | 4 | 12 | 2 | | 1 | 4 | 12 | 3 | | 1 | 4 | 12 | 7 | | 1 | 4 | 12 | 9 | | 1 | 4 | 12 | 8 | | 1 | 4 | 13 | 1 | | 1 | 4 | 13 | 2 | | 1 | 4 | 13 | 3 | | 1 | 4 | 13 | 7 | | 1 | 4 | 13 | 9 | | 1 | 4 | 13 | 8 | | 1 | 5 | 1 | 1 | | 1 | 5 | 1 | 2 | | 1 | 5 | 1 | 3 | | 1 | 5 | 1 | 7 | | 1 | 5 | 1 | 9 | | 1 | 5 | 1 | 8 | | 1 | 5 | 6 | 1 | | 1 | 5 | 6 | 2 | | 1 | 5 | 6 | 3 | | 1 | 5 | 6 | 7 | | 1 | 5 | 6 | 9 | | 1 | 5 | 6 | 8 | | 1 | 5 | 9 | 1 | | 1 | 5 | 9 | 2 | | 1 | 5 | 9 | 3 | | 1 | 5 | 9 | 7 | | 1 | 5 | 9 | 9 | | 1 | 5 | 9 | 8 | | 1 | 5 | 11 | 1 | | 1 | 5 | 11 | 2 | | 1 | 5 | 11 | 3 | | 1 | 5 | 11 | 7 | | 1 | 5 | 11 | 9 | | 1 | 5 | 11 | 8 | | 1 | 5 | 12 | 1 | | 1 | 5 | 12 | 2 | | 1 | 5 | 12 | 3 | | 1 | 5 | 12 | 7 | | 1 | 5 | 12 | 9 | | 1 | 5 | 12 | 8 | | 1 | 5 | 13 | 1 | | 1 | 5 | 13 | 2 | | 1 | 5 | 13 | 3 | | 1 | 5 | 13 | 7 | | 1 | 5 | 13 | 9 | | 1 | 5 | 13 | 8 | | 1 | 6 | 1 | 1 | | 1 | 6 | 1 | 2 | | 1 | 6 | 1 | 3 | | 1 | 6 | 1 | 7 | | 1 | 6 | 1 | 9 | | 1 | 6 | 1 | 8 | | 1 | 6 | 6 | 1 | | 1 | 6 | 6 | 2 | | 1 | 6 | 6 | 3 | | 1 | 6 | 6 | 7 | | 1 | 6 | 6 | 9 | | 1 | 6 | 6 | 8 | | 1 | 6 | 9 | 1 | | 1 | 6 | 9 | 2 | | 1 | 6 | 9 | 3 | | 1 | 6 | 9 | 7 | | 1 | 6 | 9 | 9 | | 1 | 6 | 9 | 8 | | 1 | 6 | 11 | 1 | | 1 | 6 | 11 | 2 | | 1 | 6 | 11 | 3 | | 1 | 6 | 11 | 7 | | 1 | 6 | 11 | 9 | | 1 | 6 | 11 | 8 | | 1 | 6 | 12 | 1 | | 1 | 6 | 12 | 2 | | 1 | 6 | 12 | 3 | | 1 | 6 | 12 | 7 | | 1 | 6 | 12 | 9 | | 1 | 6 | 12 | 8 | | 1 | 6 | 13 | 1 | | 1 | 6 | 13 | 2 | | 1 | 6 | 13 | 3 | | 1 | 6 | 13 | 7 | | 1 | 6 | 13 | 9 | | 1 | 6 | 13 | 8 | | 1 | 9 | 1 | 1 | | 1 | 9 | 1 | 2 | | 1 | 9 | 1 | 3 | | 1 | 9 | 1 | 7 | | 1 | 9 | 1 | 9 | | 1 | 9 | 1 | 8 | | 1 | 9 | 6 | 1 | | 1 | 9 | 6 | 2 | | 1 | 9 | 6 | 3 | | 1 | 9 | 6 | 7 | | 1 | 9 | 6 | 9 | | 1 | 9 | 6 | 8 | | 1 | 9 | 9 | 1 | | 1 | 9 | 9 | 2 | | 1 | 9 | 9 | 3 | | 1 | 9 | 9 | 7 | | 1 | 9 | 9 | 9 | | 1 | 9 | 9 | 8 | | 1 | 9 | 11 | 1 | | 1 | 9 | 11 | 2 | | 1 | 9 | 11 | 3 | | 1 | 9 | 11 | 7 | | 1 | 9 | 11 | 9 | | 1 | 9 | 11 | 8 | | 1 | 9 | 12 | 1 | | 1 | 9 | 12 | 2 | | 1 | 9 | 12 | 3 | | 1 | 9 | 12 | 7 | | 1 | 9 | 12 | 9 | | 1 | 9 | 12 | 8 | | 1 | 9 | 13 | 1 | | 1 | 9 | 13 | 2 | | 1 | 9 | 13 | 3 | | 1 | 9 | 13 | 7 | | 1 | 9 | 13 | 9 | | 1 | 9 | 13 | 8 | | 1 | 8 | 1 | 1 | | 1 | 8 | 1 | 2 | | 1 | 8 | 1 | 3 | | 1 | 8 | 1 | 7 | | 1 | 8 | 1 | 9 | | 1 | 8 | 1 | 8 | | 1 | 8 | 6 | 1 | | 1 | 8 | 6 | 2 | | 1 | 8 | 6 | 3 | | 1 | 8 | 6 | 7 | | 1 | 8 | 6 | 9 | | 1 | 8 | 6 | 8 | | 1 | 8 | 9 | 1 | | 1 | 8 | 9 | 2 | | 1 | 8 | 9 | 3 | | 1 | 8 | 9 | 7 | | 1 | 8 | 9 | 9 | | 1 | 8 | 9 | 8 | | 1 | 8 | 11 | 1 | | 1 | 8 | 11 | 2 | | 1 | 8 | 11 | 3 | | 1 | 8 | 11 | 7 | | 1 | 8 | 11 | 9 | | 1 | 8 | 11 | 8 | | 1 | 8 | 12 | 1 | | 1 | 8 | 12 | 2 | | 1 | 8 | 12 | 3 | | 1 | 8 | 12 | 7 | | 1 | 8 | 12 | 9 | | 1 | 8 | 12 | 8 | | 1 | 8 | 13 | 1 | | 1 | 8 | 13 | 2 | | 1 | 8 | 13 | 3 | | 1 | 8 | 13 | 7 | | 1 | 8 | 13 | 9 | | 1 | 8 | 13 | 8 | | 1 | 10 | 1 | 1 | | 1 | 10 | 1 | 2 | | 1 | 10 | 1 | 3 | | 1 | 10 | 1 | 7 | | 1 | 10 | 1 | 9 | | 1 | 10 | 1 | 8 | | 1 | 10 | 6 | 1 | | 1 | 10 | 6 | 2 | | 1 | 10 | 6 | 3 | | 1 | 10 | 6 | 7 | | 1 | 10 | 6 | 9 | | 1 | 10 | 6 | 8 | | 1 | 10 | 9 | 1 | | 1 | 10 | 9 | 2 | | 1 | 10 | 9 | 3 | | 1 | 10 | 9 | 7 | | 1 | 10 | 9 | 9 | | 1 | 10 | 9 | 8 | | 1 | 10 | 11 | 1 | | 1 | 10 | 11 | 2 | | 1 | 10 | 11 | 3 | | 1 | 10 | 11 | 7 | | 1 | 10 | 11 | 9 | | 1 | 10 | 11 | 8 | | 1 | 10 | 12 | 1 | | 1 | 10 | 12 | 2 | | 1 | 10 | 12 | 3 | | 1 | 10 | 12 | 7 | | 1 | 10 | 12 | 9 | | 1 | 10 | 12 | 8 | | 1 | 10 | 13 | 1 | | 1 | 10 | 13 | 2 | | 1 | 10 | 13 | 3 | | 1 | 10 | 13 | 7 | | 1 | 10 | 13 | 9 | | 1 | 10 | 13 | 8 | | 1 | 11 | 1 | 1 | | 1 | 11 | 1 | 2 | | 1 | 11 | 1 | 3 | | 1 | 11 | 1 | 7 | | 1 | 11 | 1 | 9 | | 1 | 11 | 1 | 8 | | 1 | 11 | 6 | 1 | | 1 | 11 | 6 | 2 | | 1 | 11 | 6 | 3 | | 1 | 11 | 6 | 7 | | 1 | 11 | 6 | 9 | | 1 | 11 | 6 | 8 | | 1 | 11 | 9 | 1 | | 1 | 11 | 9 | 2 | | 1 | 11 | 9 | 3 | | 1 | 11 | 9 | 7 | | 1 | 11 | 9 | 9 | | 1 | 11 | 9 | 8 | | 1 | 11 | 11 | 1 | | 1 | 11 | 11 | 2 | | 1 | 11 | 11 | 3 | | 1 | 11 | 11 | 7 | | 1 | 11 | 11 | 9 | | 1 | 11 | 11 | 8 | | 1 | 11 | 12 | 1 | | 1 | 11 | 12 | 2 | | 1 | 11 | 12 | 3 | | 1 | 11 | 12 | 7 | | 1 | 11 | 12 | 9 | | 1 | 11 | 12 | 8 | | 1 | 11 | 13 | 1 | | 1 | 11 | 13 | 2 | | 1 | 11 | 13 | 3 | | 1 | 11 | 13 | 7 | | 1 | 11 | 13 | 9 | | 1 | 11 | 13 | 8 | | 1 | 12 | 1 | 1 | | 1 | 12 | 1 | 2 | | 1 | 12 | 1 | 3 | | 1 | 12 | 1 | 7 | | 1 | 12 | 1 | 9 | | 1 | 12 | 1 | 8 | | 1 | 12 | 6 | 1 | | 1 | 12 | 6 | 2 | | 1 | 12 | 6 | 3 | | 1 | 12 | 6 | 7 | | 1 | 12 | 6 | 9 | | 1 | 12 | 6 | 8 | | 1 | 12 | 9 | 1 | | 1 | 12 | 9 | 2 | | 1 | 12 | 9 | 3 | | 1 | 12 | 9 | 7 | | 1 | 12 | 9 | 9 | | 1 | 12 | 9 | 8 | | 1 | 12 | 11 | 1 | | 1 | 12 | 11 | 2 | | 1 | 12 | 11 | 3 | | 1 | 12 | 11 | 7 | | 1 | 12 | 11 | 9 | | 1 | 12 | 11 | 8 | | 1 | 12 | 12 | 1 | | 1 | 12 | 12 | 2 | | 1 | 12 | 12 | 3 | | 1 | 12 | 12 | 7 | | 1 | 12 | 12 | 9 | | 1 | 12 | 12 | 8 | | 1 | 12 | 13 | 1 | | 1 | 12 | 13 | 2 | | 1 | 12 | 13 | 3 | | 1 | 12 | 13 | 7 | | 1 | 12 | 13 | 9 | | 1 | 12 | 13 | 8 | | 1 | 13 | 1 | 1 | | 1 | 13 | 1 | 2 | | 1 | 13 | 1 | 3 | | 1 | 13 | 1 | 7 | | 1 | 13 | 1 | 9 | | 1 | 13 | 1 | 8 | | 1 | 13 | 6 | 1 | | 1 | 13 | 6 | 2 | | 1 | 13 | 6 | 3 | | 1 | 13 | 6 | 7 | | 1 | 13 | 6 | 9 | | 1 | 13 | 6 | 8 | | 1 | 13 | 9 | 1 | | 1 | 13 | 9 | 2 | | 1 | 13 | 9 | 3 | | 1 | 13 | 9 | 7 | | 1 | 13 | 9 | 9 | | 1 | 13 | 9 | 8 | | 1 | 13 | 11 | 1 | | 1 | 13 | 11 | 2 | | 1 | 13 | 11 | 3 | | 1 | 13 | 11 | 7 | | 1 | 13 | 11 | 9 | | 1 | 13 | 11 | 8 | | 1 | 13 | 12 | 1 | | 1 | 13 | 12 | 2 | | 1 | 13 | 12 | 3 | | 1 | 13 | 12 | 7 | | 1 | 13 | 12 | 9 | | 1 | 13 | 12 | 8 | | 1 | 13 | 13 | 1 | | 1 | 13 | 13 | 2 | | 1 | 13 | 13 | 3 | | 1 | 13 | 13 | 7 | | 1 | 13 | 13 | 9 | | 1 | 13 | 13 | 8 | | 1 | 14 | 1 | 1 | | 1 | 14 | 1 | 2 | | 1 | 14 | 1 | 3 | | 1 | 14 | 1 | 7 | | 1 | 14 | 1 | 9 | | 1 | 14 | 1 | 8 | | 1 | 14 | 6 | 1 | | 1 | 14 | 6 | 2 | | 1 | 14 | 6 | 3 | | 1 | 14 | 6 | 7 | | 1 | 14 | 6 | 9 | | 1 | 14 | 6 | 8 | | 1 | 14 | 9 | 1 | | 1 | 14 | 9 | 2 | | 1 | 14 | 9 | 3 | | 1 | 14 | 9 | 7 | | 1 | 14 | 9 | 9 | | 1 | 14 | 9 | 8 | | 1 | 14 | 11 | 1 | | 1 | 14 | 11 | 2 | | 1 | 14 | 11 | 3 | | 1 | 14 | 11 | 7 | | 1 | 14 | 11 | 9 | | 1 | 14 | 11 | 8 | | 1 | 14 | 12 | 1 | | 1 | 14 | 12 | 2 | | 1 | 14 | 12 | 3 | | 1 | 14 | 12 | 7 | | 1 | 14 | 12 | 9 | | 1 | 14 | 12 | 8 | | 1 | 14 | 13 | 1 | | 1 | 14 | 13 | 2 | | 1 | 14 | 13 | 3 | | 1 | 14 | 13 | 7 | | 1 | 14 | 13 | 9 | | 1 | 14 | 13 | 8 | | 1 | 15 | 1 | 1 | | 1 | 15 | 1 | 2 | | 1 | 15 | 1 | 3 | | 1 | 15 | 1 | 7 | | 1 | 15 | 1 | 9 | | 1 | 15 | 1 | 8 | | 1 | 15 | 6 | 1 | | 1 | 15 | 6 | 2 | | 1 | 15 | 6 | 3 | | 1 | 15 | 6 | 7 | | 1 | 15 | 6 | 9 | | 1 | 15 | 6 | 8 | | 1 | 15 | 9 | 1 | | 1 | 15 | 9 | 2 | | 1 | 15 | 9 | 3 | | 1 | 15 | 9 | 7 | | 1 | 15 | 9 | 9 | | 1 | 15 | 9 | 8 | | 1 | 15 | 11 | 1 | | 1 | 15 | 11 | 2 | | 1 | 15 | 11 | 3 | | 1 | 15 | 11 | 7 | | 1 | 15 | 11 | 9 | | 1 | 15 | 11 | 8 | | 1 | 15 | 12 | 1 | | 1 | 15 | 12 | 2 | | 1 | 15 | 12 | 3 | | 1 | 15 | 12 | 7 | | 1 | 15 | 12 | 9 | | 1 | 15 | 12 | 8 | | 1 | 15 | 13 | 1 | | 1 | 15 | 13 | 2 | | 1 | 15 | 13 | 3 | | 1 | 15 | 13 | 7 | | 1 | 15 | 13 | 9 | | 1 | 15 | 13 | 8 | | 1 | 16 | 1 | 1 | | 1 | 16 | 1 | 2 | | 1 | 16 | 1 | 3 | | 1 | 16 | 1 | 7 | | 1 | 16 | 1 | 9 | | 1 | 16 | 1 | 8 | | 1 | 16 | 6 | 1 | | 1 | 16 | 6 | 2 | | 1 | 16 | 6 | 3 | | 1 | 16 | 6 | 7 | | 1 | 16 | 6 | 9 | | 1 | 16 | 6 | 8 | | 1 | 16 | 9 | 1 | | 1 | 16 | 9 | 2 | | 1 | 16 | 9 | 3 | | 1 | 16 | 9 | 7 | | 1 | 16 | 9 | 9 | | 1 | 16 | 9 | 8 | | 1 | 16 | 11 | 1 | | 1 | 16 | 11 | 2 | | 1 | 16 | 11 | 3 | | 1 | 16 | 11 | 7 | | 1 | 16 | 11 | 9 | | 1 | 16 | 11 | 8 | | 1 | 16 | 12 | 1 | | 1 | 16 | 12 | 2 | | 1 | 16 | 12 | 3 | | 1 | 16 | 12 | 7 | | 1 | 16 | 12 | 9 | | 1 | 16 | 12 | 8 | | 1 | 16 | 13 | 1 | | 1 | 16 | 13 | 2 | | 1 | 16 | 13 | 3 | | 1 | 16 | 13 | 7 | | 1 | 16 | 13 | 9 | | 1 | 16 | 13 | 8 | | 1 | 17 | 1 | 1 | | 1 | 17 | 1 | 2 | | 1 | 17 | 1 | 3 | | 1 | 17 | 1 | 7 | | 1 | 17 | 1 | 9 | | 1 | 17 | 1 | 8 | | 1 | 17 | 6 | 1 | | 1 | 17 | 6 | 2 | | 1 | 17 | 6 | 3 | | 1 | 17 | 6 | 7 | | 1 | 17 | 6 | 9 | | 1 | 17 | 6 | 8 | | 1 | 17 | 9 | 1 | | 1 | 17 | 9 | 2 | | 1 | 17 | 9 | 3 | | 1 | 17 | 9 | 7 | | 1 | 17 | 9 | 9 | | 1 | 17 | 9 | 8 | | 1 | 17 | 11 | 1 | | 1 | 17 | 11 | 2 | | 1 | 17 | 11 | 3 | | 1 | 17 | 11 | 7 | | 1 | 17 | 11 | 9 | | 1 | 17 | 11 | 8 | | 1 | 17 | 12 | 1 | | 1 | 17 | 12 | 2 | | 1 | 17 | 12 | 3 | | 1 | 17 | 12 | 7 | | 1 | 17 | 12 | 9 | | 1 | 17 | 12 | 8 | | 1 | 17 | 13 | 1 | | 1 | 17 | 13 | 2 | | 1 | 17 | 13 | 3 | | 1 | 17 | 13 | 7 | | 1 | 17 | 13 | 9 | | 1 | 17 | 13 | 8 | | 1 | 18 | 1 | 1 | | 1 | 18 | 1 | 2 | | 1 | 18 | 1 | 3 | | 1 | 18 | 1 | 7 | | 1 | 18 | 1 | 9 | | 1 | 18 | 1 | 8 | | 1 | 18 | 6 | 1 | | 1 | 18 | 6 | 2 | | 1 | 18 | 6 | 3 | | 1 | 18 | 6 | 7 | | 1 | 18 | 6 | 9 | | 1 | 18 | 6 | 8 | | 1 | 18 | 9 | 1 | | 1 | 18 | 9 | 2 | | 1 | 18 | 9 | 3 | | 1 | 18 | 9 | 7 | | 1 | 18 | 9 | 9 | | 1 | 18 | 9 | 8 | | 1 | 18 | 11 | 1 | | 1 | 18 | 11 | 2 | | 1 | 18 | 11 | 3 | | 1 | 18 | 11 | 7 | | 1 | 18 | 11 | 9 | | 1 | 18 | 11 | 8 | | 1 | 18 | 12 | 1 | | 1 | 18 | 12 | 2 | | 1 | 18 | 12 | 3 | | 1 | 18 | 12 | 7 | | 1 | 18 | 12 | 9 | | 1 | 18 | 12 | 8 | | 1 | 18 | 13 | 1 | | 1 | 18 | 13 | 2 | | 1 | 18 | 13 | 3 | | 1 | 18 | 13 | 7 | | 1 | 18 | 13 | 9 | | 1 | 18 | 13 | 8 | | 1 | 19 | 1 | 1 | | 1 | 19 | 1 | 2 | | 1 | 19 | 1 | 3 | | 1 | 19 | 1 | 7 | | 1 | 19 | 1 | 9 | | 1 | 19 | 1 | 8 | | 1 | 19 | 6 | 1 | | 1 | 19 | 6 | 2 | | 1 | 19 | 6 | 3 | | 1 | 19 | 6 | 7 | | 1 | 19 | 6 | 9 | | 1 | 19 | 6 | 8 | | 1 | 19 | 9 | 1 | | 1 | 19 | 9 | 2 | | 1 | 19 | 9 | 3 | | 1 | 19 | 9 | 7 | | 1 | 19 | 9 | 9 | | 1 | 19 | 9 | 8 | | 1 | 19 | 11 | 1 | | 1 | 19 | 11 | 2 | | 1 | 19 | 11 | 3 | | 1 | 19 | 11 | 7 | | 1 | 19 | 11 | 9 | | 1 | 19 | 11 | 8 | | 1 | 19 | 12 | 1 | | 1 | 19 | 12 | 2 | | 1 | 19 | 12 | 3 | | 1 | 19 | 12 | 7 | | 1 | 19 | 12 | 9 | | 1 | 19 | 12 | 8 | | 1 | 19 | 13 | 1 | | 1 | 19 | 13 | 2 | | 1 | 19 | 13 | 3 | | 1 | 19 | 13 | 7 | | 1 | 19 | 13 | 9 | | 1 | 19 | 13 | 8 | | 1 | 20 | 1 | 1 | | 1 | 20 | 1 | 2 | | 1 | 20 | 1 | 3 | | 1 | 20 | 1 | 7 | | 1 | 20 | 1 | 9 | | 1 | 20 | 1 | 8 | | 1 | 20 | 6 | 1 | | 1 | 20 | 6 | 2 | | 1 | 20 | 6 | 3 | | 1 | 20 | 6 | 7 | | 1 | 20 | 6 | 9 | | 1 | 20 | 6 | 8 | | 1 | 20 | 9 | 1 | | 1 | 20 | 9 | 2 | | 1 | 20 | 9 | 3 | | 1 | 20 | 9 | 7 | | 1 | 20 | 9 | 9 | | 1 | 20 | 9 | 8 | | 1 | 20 | 11 | 1 | | 1 | 20 | 11 | 2 | | 1 | 20 | 11 | 3 | | 1 | 20 | 11 | 7 | | 1 | 20 | 11 | 9 | | 1 | 20 | 11 | 8 | | 1 | 20 | 12 | 1 | | 1 | 20 | 12 | 2 | | 1 | 20 | 12 | 3 | | 1 | 20 | 12 | 7 | | 1 | 20 | 12 | 9 | | 1 | 20 | 12 | 8 | | 1 | 20 | 13 | 1 | | 1 | 20 | 13 | 2 | | 1 | 20 | 13 | 3 | | 1 | 20 | 13 | 7 | | 1 | 20 | 13 | 9 | | 1 | 20 | 13 | 8 | | 1 | 21 | 1 | 1 | | 1 | 21 | 1 | 2 | | 1 | 21 | 1 | 3 | | 1 | 21 | 1 | 7 | | 1 | 21 | 1 | 9 | | 1 | 21 | 1 | 8 | | 1 | 21 | 6 | 1 | | 1 | 21 | 6 | 2 | | 1 | 21 | 6 | 3 | | 1 | 21 | 6 | 7 | | 1 | 21 | 6 | 9 | | 1 | 21 | 6 | 8 | | 1 | 21 | 9 | 1 | | 1 | 21 | 9 | 2 | | 1 | 21 | 9 | 3 | | 1 | 21 | 9 | 7 | | 1 | 21 | 9 | 9 | | 1 | 21 | 9 | 8 | | 1 | 21 | 11 | 1 | | 1 | 21 | 11 | 2 | | 1 | 21 | 11 | 3 | | 1 | 21 | 11 | 7 | | 1 | 21 | 11 | 9 | | 1 | 21 | 11 | 8 | | 1 | 21 | 12 | 1 | | 1 | 21 | 12 | 2 | | 1 | 21 | 12 | 3 | | 1 | 21 | 12 | 7 | | 1 | 21 | 12 | 9 | | 1 | 21 | 12 | 8 | | 1 | 21 | 13 | 1 | | 1 | 21 | 13 | 2 | | 1 | 21 | 13 | 3 | | 1 | 21 | 13 | 7 | | 1 | 21 | 13 | 9 | | 1 | 21 | 13 | 8 | | 1 | 22 | 1 | 1 | | 1 | 22 | 1 | 2 | | 1 | 22 | 1 | 3 | | 1 | 22 | 1 | 7 | | 1 | 22 | 1 | 9 | | 1 | 22 | 1 | 8 | | 1 | 22 | 6 | 1 | | 1 | 22 | 6 | 2 | | 1 | 22 | 6 | 3 | | 1 | 22 | 6 | 7 | | 1 | 22 | 6 | 9 | | 1 | 22 | 6 | 8 | | 1 | 22 | 9 | 1 | | 1 | 22 | 9 | 2 | | 1 | 22 | 9 | 3 | | 1 | 22 | 9 | 7 | | 1 | 22 | 9 | 9 | | 1 | 22 | 9 | 8 | | 1 | 22 | 11 | 1 | | 1 | 22 | 11 | 2 | | 1 | 22 | 11 | 3 | | 1 | 22 | 11 | 7 | | 1 | 22 | 11 | 9 | | 1 | 22 | 11 | 8 | | 1 | 22 | 12 | 1 | | 1 | 22 | 12 | 2 | | 1 | 22 | 12 | 3 | | 1 | 22 | 12 | 7 | | 1 | 22 | 12 | 9 | | 1 | 22 | 12 | 8 | | 1 | 22 | 13 | 1 | | 1 | 22 | 13 | 2 | | 1 | 22 | 13 | 3 | | 1 | 22 | 13 | 7 | | 1 | 22 | 13 | 9 | | 1 | 22 | 13 | 8 | | 1 | 23 | 1 | 1 | | 1 | 23 | 1 | 2 | | 1 | 23 | 1 | 3 | | 1 | 23 | 1 | 7 | | 1 | 23 | 1 | 9 | | 1 | 23 | 1 | 8 | | 1 | 23 | 6 | 1 | | 1 | 23 | 6 | 2 | | 1 | 23 | 6 | 3 | | 1 | 23 | 6 | 7 | | 1 | 23 | 6 | 9 | | 1 | 23 | 6 | 8 | | 1 | 23 | 9 | 1 | | 1 | 23 | 9 | 2 | | 1 | 23 | 9 | 3 | | 1 | 23 | 9 | 7 | | 1 | 23 | 9 | 9 | | 1 | 23 | 9 | 8 | | 1 | 23 | 11 | 1 | | 1 | 23 | 11 | 2 | | 1 | 23 | 11 | 3 | | 1 | 23 | 11 | 7 | | 1 | 23 | 11 | 9 | | 1 | 23 | 11 | 8 | | 1 | 23 | 12 | 1 | | 1 | 23 | 12 | 2 | | 1 | 23 | 12 | 3 | | 1 | 23 | 12 | 7 | | 1 | 23 | 12 | 9 | | 1 | 23 | 12 | 8 | | 1 | 23 | 13 | 1 | | 1 | 23 | 13 | 2 | | 1 | 23 | 13 | 3 | | 1 | 23 | 13 | 7 | | 1 | 23 | 13 | 9 | | 1 | 23 | 13 | 8 | | 1 | 24 | 1 | 1 | | 1 | 24 | 1 | 2 | | 1 | 24 | 1 | 3 | | 1 | 24 | 1 | 7 | | 1 | 24 | 1 | 9 | | 1 | 24 | 1 | 8 | | 1 | 24 | 6 | 1 | | 1 | 24 | 6 | 2 | | 1 | 24 | 6 | 3 | | 1 | 24 | 6 | 7 | | 1 | 24 | 6 | 9 | | 1 | 24 | 6 | 8 | | 1 | 24 | 9 | 1 | | 1 | 24 | 9 | 2 | | 1 | 24 | 9 | 3 | | 1 | 24 | 9 | 7 | | 1 | 24 | 9 | 9 | | 1 | 24 | 9 | 8 | | 1 | 24 | 11 | 1 | | 1 | 24 | 11 | 2 | | 1 | 24 | 11 | 3 | | 1 | 24 | 11 | 7 | | 1 | 24 | 11 | 9 | | 1 | 24 | 11 | 8 | | 1 | 24 | 12 | 1 | | 1 | 24 | 12 | 2 | | 1 | 24 | 12 | 3 | | 1 | 24 | 12 | 7 | | 1 | 24 | 12 | 9 | | 1 | 24 | 12 | 8 | | 1 | 24 | 13 | 1 | | 1 | 24 | 13 | 2 | | 1 | 24 | 13 | 3 | | 1 | 24 | 13 | 7 | | 1 | 24 | 13 | 9 | | 1 | 24 | 13 | 8 | +----+------+------+------+ 756 rows in set (0.01 sec)
Что по твоему делает внешнее объединение? (LEFT [OUTTER] JOIN) Оно также объединяет таблицы, как и внутреннее объединение ([INNER] JOIN), но для вместо отсутствующих для объединения строк добавляет строку из NULL-значений. 1 * 21 * 6 * 6 = 756 Добавлено через 2 минуты и 26 секунд:Через LEFT JOIN можно подключать когда в каждой дополнительной таблице есть по 0 или 1 подходящей строке (т.е. поле связи в подключаемой таблице - первичный ключ), либо таблица должна быть одна.
|
|
« Последнее редактирование: 17-06-2011 18:31 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Kivals
|
|
« Ответ #31 : 17-06-2011 18:37 » |
|
Т.е. как вариант - сначала свернуть подчиненные таблицы по первичному ключу (select id_who, SUM(...), SUM(...) from xxx group by id_who)? а потом уже это объединять с таблицей users?
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #32 : 17-06-2011 18:38 » |
|
mysql> SELECT id, (vb + pb + ab) / (vv + pv + av), vb, pb, ab, vv, pv, av -> FROM ( -> SELECT users.id, -> (SELECT IFNULL(SUM(ballet), 0) FROM videos WHERE id_who = users.id) vb, -> (SELECT IFNULL(SUM(ballet), 0) FROM photos WHERE id_who = users.id) pb, -> (SELECT IFNULL(SUM(ballet), 0) FROM articles WHERE id_who = users.id) ab, -> (SELECT IFNULL(SUM(voting), 0) FROM videos WHERE id_who = users.id) vv, -> (SELECT IFNULL(SUM(voting), 0) FROM photos WHERE id_who = users.id) pv, -> (SELECT IFNULL(SUM(voting), 0) FROM articles WHERE id_who = users.id) av -> FROM users -> ) t; +----+---------------------------------+------+------+------+------+------+------+ | id | (vb + pb + ab) / (vv + pv + av) | vb | pb | ab | vv | pv | av | +----+---------------------------------+------+------+------+------+------+------+ | 1 | 4.5000 | 24 | 14 | 7 | 5 | 3 | 2 | | 2 | NULL | 0 | 0 | 0 | 0 | 0 | 0 | | 3 | 3.6667 | 0 | 11 | 0 | 0 | 3 | 0 | | 44 | 4.7500 | 19 | 0 | 0 | 4 | 0 | 0 | +----+---------------------------------+------+------+------+------+------+------+ 4 rows in set (0.00 sec)
Добавлено через 1 минуту и 51 секунду:Поля id_who рекомендую проиндексировать. Стоит проверить, какой ключ больше подходит (но для тестов нужно строк на 1-2 порядка больше): KEY id_who (id_who) или UNIQUE id_who_id (id_who, id). Добавлено через 2 минуты и 47 секунд:Макс, по твоему посту: 1. SELECT длинная_длинная_формула AS aaa, COUNT(*) ... GROUP BY aaa 2. SELECT ..., COUNT(*) cnt ... GROUP BY ... HAVING cnt > 1 3. Аналогично 1 и 2 для ORDER BY.
|
|
« Последнее редактирование: 17-06-2011 18:49 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Sla
|
|
« Ответ #33 : 17-06-2011 21:07 » |
|
я в шоке, то что должно работать как понимаешь, не работает. Ощущение такое, что не работает left join при нескольких таблицах SELECT users.id,users.nick,users.photo, videos.ballet,photos.ballet,articles.ballet FROM users LEFT JOIN videos ON videos.id_who=users.id LEFT JOIN photos ON photos.id_who=users.id LEFT JOIN articles ON articles.id_who=users.id where users.id=1
Посмотрите сколько строк выберется... Добавлено через 17 минут и 40 секунд:неужели в таком случае происходит декартово произведение?
|
|
« Последнее редактирование: 17-06-2011 21:25 от Sla »
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Kivals
|
|
« Ответ #34 : 18-06-2011 03:07 » |
|
Sla, нет, не произведение - просто left join выполняется последовательно, от результата предыдущего выполнения. См. есть таблицы: users: id name 1 Вася 2 Петя
data1: who data1 1 11 1 12 2 21 2 22
data2: who data2 1 11 1 12 2 21 2 22
select users.*, data1.data1 users left join data 1 даст нам правильный результат, но обрати внимание сколько строк: id name data1 1 Вася 11 1 Вася 12 2 Петя 21 2 Петя 22
Теперь если применить еще один left join с data2 то получим еще больше строк....
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #35 : 18-06-2011 06:44 » |
|
Произведение-произведение. Только по правилам внешнего объединения.
Таблица1 (+) Таблица2(условие) (+) Таблица3(условие)
Слав, так всегда было...
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Kivals
|
|
« Ответ #36 : 18-06-2011 08:09 » |
|
Offtopic: Ром, ну может и произведение, но не декартово: Прямое или декартово произведение множеств — множество, элементами которого являются всевозможные упорядоченные пары элементов исходных двух множеств. Всевозможных пар было бы больше
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #37 : 18-06-2011 08:18 » |
|
Ярослав, даже более, чем декартово - ведь тут умножения на возможный ноль строк не будет. В остальном тоже самое.
Посмотри вторую "консоль" поста №31. На одну строку users (по WHERE), было выбрано 21 строка из videos, потом результат умножен на 6 строк photos и еще на 6 строк articles. В итоге - 756 строк. Иной техники объединения я представить себе не могу.
|
|
« Последнее редактирование: 18-06-2011 08:20 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Kivals
|
|
« Ответ #38 : 18-06-2011 08:22 » |
|
Ром, декартово - это полное умножение строк, т.е. в моем примере получили бы 8 строк, а не 4. Декартово произведение - это когда таблицы просто перечислены в блоке from без указания связей
Добавлено через 2 минуты и 8 секунд: P.S. из твоих объяснений я уже понял логику работы left join и понял в чем "ошибка" в исходном запросе
|
|
« Последнее редактирование: 18-06-2011 08:25 от Kivals »
|
Записан
|
|
|
|
Сергей Добросклонов
|
|
« Ответ #39 : 18-06-2011 11:29 » |
|
mysql> SELECT id, (vb + pb + ab) / (vv + pv + av), vb, pb, ab, vv, pv, av -> FROM ( -> SELECT users.id, -> (SELECT IFNULL(SUM(ballet), 0) FROM videos WHERE id_who = users.id) vb, -> (SELECT IFNULL(SUM(ballet), 0) FROM photos WHERE id_who = users.id) pb, -> (SELECT IFNULL(SUM(ballet), 0) FROM articles WHERE id_who = users.id) ab, -> (SELECT IFNULL(SUM(voting), 0) FROM videos WHERE id_who = users.id) vv, -> (SELECT IFNULL(SUM(voting), 0) FROM photos WHERE id_who = users.id) pv, -> (SELECT IFNULL(SUM(voting), 0) FROM articles WHERE id_who = users.id) av -> FROM users -> ) t;
Пашет как надо. RXL, спасибо огромное!
|
|
|
Записан
|
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #40 : 19-06-2011 07:00 » |
|
Т.е. как вариант - сначала свернуть подчиненные таблицы по первичному ключу (select id_who, SUM(...), SUM(...) from xxx group by id_who)? а потом уже это объединять с таблицей users?
а моего решения никто не заметил чтоли? RXL, и сколько же там проходов по таблицам будет? HASH JOIN пойдет или все в NESTED LOOP-ах будет?
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
McZim
|
|
« Ответ #41 : 19-06-2011 07:05 » |
|
PooH, с точки зрения оракла все будет зависить от статистики по объектам и наличие необходимых объектов. Думаю в мускуле так же.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
|
|
« Ответ #42 : 19-06-2011 07:42 » |
|
PooH, я видел твой вариант. Но в такой форме нельзя сделать зависимости в подчиненных таблицах и выбрать данные по одному пользователю или по списку. Если же выбирать по всем пользователям, то твой вариант оптимальнее. Кстати, id_who не является первичным ключем. Чтение таблиц неизбежно, т.к. нужны поля ballet и voting. Т.е. если сперва сгруппировать, то будет полное чтение таблицы. Если же группировать по равенству ключа, то чтение выборочное. Попробую залить таблицы заново и проверить план. Добавлено через 16 минут и 28 секунд:Первый запрос отсюда: https://forum.shelek.ru/index.php/topic,27290.msg262661.html#msg262661+----+-------------+------------+-------+---------------+---------+---------+------+------+----------+----------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+-------+---------------+---------+---------+------+------+----------+----------------------------------------------+ | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 4 | 100.00 | | | 2 | DERIVED | users | index | NULL | PRIMARY | 4 | NULL | 4 | 100.00 | Using index; Using temporary; Using filesort | | 2 | DERIVED | videos | ALL | NULL | NULL | NULL | NULL | 23 | 100.00 | | | 2 | DERIVED | photos | ALL | NULL | NULL | NULL | NULL | 10 | 100.00 | | | 2 | DERIVED | articles | ALL | NULL | NULL | NULL | NULL | 9 | 100.00 | | +----+-------------+------------+-------+---------------+---------+---------+------+------+----------+----------------------------------------------+
Запрос отсюда: https://forum.shelek.ru/index.php/topic,27290.msg262656.html#msg262656+----+-------------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+ | 1 | PRIMARY | u | ALL | NULL | NULL | NULL | NULL | 4 | 100.00 | | | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | | | 1 | PRIMARY | <derived3> | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | | | 1 | PRIMARY | <derived4> | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | | | 4 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 9 | 100.00 | Using temporary; Using filesort | | 3 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 10 | 100.00 | Using temporary; Using filesort | | 2 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 23 | 100.00 | Using temporary; Using filesort | +----+-------------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
Добавляю в запросы выборку только "users.id = 1". +----+-------------+------------+--------+---------------+---------+---------+------+------+----------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+--------+---------------+---------+---------+------+------+----------+-------------+ | 1 | PRIMARY | <derived2> | system | NULL | NULL | NULL | NULL | 1 | 100.00 | | | 2 | DERIVED | users | const | PRIMARY | PRIMARY | 4 | | 1 | 100.00 | Using index | | 2 | DERIVED | videos | ALL | NULL | NULL | NULL | NULL | 23 | 100.00 | | | 2 | DERIVED | photos | ALL | NULL | NULL | NULL | NULL | 10 | 100.00 | | | 2 | DERIVED | articles | ALL | NULL | NULL | NULL | NULL | 9 | 100.00 | | +----+-------------+------------+--------+---------------+---------+---------+------+------+----------+-------------+
+----+-------------+------------+-------+---------------+---------+---------+-------+------+----------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+-------+---------------+---------+---------+-------+------+----------+---------------------------------+ | 1 | PRIMARY | u | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | | | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | | | 1 | PRIMARY | <derived3> | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | | | 1 | PRIMARY | <derived4> | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | | | 4 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 9 | 100.00 | Using temporary; Using filesort | | 3 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 10 | 100.00 | Using temporary; Using filesort | | 2 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 23 | 100.00 | Using temporary; Using filesort | +----+-------------+------------+-------+---------------+---------+---------+-------+------+----------+---------------------------------+
Добавляю в подчиненные таблицы неуникальный ключ KEY (id_who). +----+-------------+------------+--------+---------------+---------+---------+------+------+----------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+--------+---------------+---------+---------+------+------+----------+-------------+ | 1 | PRIMARY | <derived2> | system | NULL | NULL | NULL | NULL | 1 | 100.00 | | | 2 | DERIVED | users | const | PRIMARY | PRIMARY | 4 | | 1 | 100.00 | Using index | | 2 | DERIVED | videos | ref | id_who | id_who | 5 | | 20 | 100.00 | | | 2 | DERIVED | photos | ref | id_who | id_who | 5 | | 5 | 100.00 | | | 2 | DERIVED | articles | ref | id_who | id_who | 5 | | 5 | 100.00 | | +----+-------------+------------+--------+---------------+---------+---------+------+------+----------+-------------+
+----+-------------+------------+-------+---------------+---------+---------+-------+------+----------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+-------+---------------+---------+---------+-------+------+----------+---------------------------------+ | 1 | PRIMARY | u | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | | | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | | | 1 | PRIMARY | <derived3> | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | | | 1 | PRIMARY | <derived4> | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | | | 4 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 9 | 100.00 | Using temporary; Using filesort | | 3 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 10 | 100.00 | Using temporary; Using filesort | | 2 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 23 | 100.00 | Using temporary; Using filesort | +----+-------------+------------+-------+---------------+---------+---------+-------+------+----------+---------------------------------+
Вот где-то так я говорил: твой запрос оптимальнее при полной выборке (причем, индексы в подчиненных таблицах ему не нужны), а мой - на адресных выборках. Добавлено через 4 минуты и 22 секунды:PooH, с точки зрения оракла все будет зависить от статистики по объектам и наличие необходимых объектов. Думаю в мускуле так же.
Макс, в MySQL статистика мало что определяет, хотя и используется оптимизатором. Чаще наоборот приходится бороться с оптимизатором хитрыми способами (например, выборка GeoIP).
|
|
« Последнее редактирование: 19-06-2011 08:10 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|