[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Подскажите с запросом к БД
Страницы: 1, 2
S.Chushkin
Господа-товарищи, что-то вы себя перемудрили, - задачка то элементарная.
select t.* from ( select max(ID) ID from table group by UserID ) a
left join table t on t.ID = a.ID
order by UserID

Выборка последних записей (по ID) для всех UserID.

_____________
Рекламка / ad.pesow.com Хрень / mr-1.ru
Миша
Цитата (S.Chushkin @ 6.04.2015 - 12:25)
Господа-товарищи, что-то вы себя перемудрили, - задачка то элементарная.
<pre class="sh_sourceCode" rel="sql"><span class="sh_keyword">select</span> t<span class="sh_symbol">.*</span> <span class="sh_keyword">from</span> <span class="sh_symbol">(</span> <span class="sh_keyword">select</span> <span class="sh_function">max(</span>ID<span class="sh_symbol">)</span> ID <span class="sh_keyword">from table group by</span> UserID <span class="sh_symbol">)</span> a
<span class="sh_keyword">left join table</span> t <span class="sh_keyword">on</span> t<span class="sh_symbol">.</span>ID <span class="sh_symbol">=</span> a<span class="sh_symbol">.</span>ID
<span class="sh_keyword">order by</span> UserID</pre>
Выборка последних записей (по ID) для всех UserID.

Аналогичный вопрос, кто может пояснить что происходит (правильно ли я понимаю):

select t.* from ( select max(ID) ID from table group by UserID ) a
left join table t on t.ID = a.ID
order by UserID


select t.* // такая запись мне не известна,  *  - это все столбцы, а t.  что это?

from () // зачем в скобках, это подзапрос?

select max(ID) ID from table group by UserID // получить столбцы id, в таблице table и сгруппировать по UserID, что означает max(ID)

a left join table t // тут объединяем, то что получилось в скобках с настоящей таблицей?

on t.ID = a.ID // c on не знаком, видимо условие

order by UserID // сортировать


То что в скобках, можно сказать так? Сгруппировать, с каждого UserID получить последний id сообщения?

_____________
Принимаю заказы, писать в ЛС
Миша
Цитата (sergeiss @ 6.04.2015 - 11:28)
Сорри, у меня в подзапросе должно быть, вроде как, m2.id_user=m1.id_user
А более детально я сейчас не могу ответить, потому что в офисе работаю.

Очень надеюсь у вас найдётся вечером немного свобоного времени, чтобы прокомментировать, то, как я понял ваш запрос и понял ли вообще. т.к. такие сложные запросы делать мне не приходилось.

_____________
Принимаю заказы, писать в ЛС
S.Chushkin
Цитата (Медведь @ 6.04.2015 - 13:49)
Аналогичный вопрос, кто может пояснить что происходит (правильно ли я понимаю):

Скачайте доку (http://dev.mysql.com/doc/) - там всё описано подробно.
Основы надо знать, иначе там (в sql) делать нечего.
Цитата
Сгруппировать, с каждого UserID получить последний id сообщения?

Правильно так: Сгруппировать по юзерИД. В каждой группе найти максимальный ИД.
Естественно, ИД должен быть с параметром AUTO_INCREMENT (или заполняться аналогом его алгоритма), чтобы "максиамльный ИД" соотвествовал "последней записи". Вместо ИД можно использовать время создания записи, например (но с умом!).


_____________
Рекламка / ad.pesow.com Хрень / mr-1.ru
Игорь_Vasinsky
Цитата
время создания записи, например (но с умом!).

тоже так считаю.

_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
Миша

Ждём совета мудрейших, кто всё по полочкам разложит.


Именно объяснить логику того, что происходит. Я написал как понимаю, теперь вопрос: правильно ли понимаю?

_____________
Принимаю заказы, писать в ЛС
Игорь_Vasinsky
Цитата
select t.* from ( select max(ID) ID from table group by UserID ) a
left join table t on t.ID = a.ID
order by UserID


По внутреннему подзапросу
Цитата
select max(ID) ID from table group by UserID


в результате ты получишь строки с максимальным ID и сгруппированные по пользователям - т.е. 1 пользователь - одна строка - максимальный ID

после этого - эта выборка будет использоваться как таблица - т.е.

Цитата
select t.* from
из основного запроса - будет выбирать именно из предыдущей описанной выборки

Цитата
left join table t on t.ID = a.ID


весь набор строк из основного запроса будет дополнен столбцами из table - с условием t.ID = a.ID

"a" и "t" - это алиасы "таблиц"

"а" это

Цитата
select t.* from ( select max(ID) ID from table group by UserID )


select же вернёт табличное значение

"t" это table


В итоге всё будет отсортировано по

Цитата
order by UserID


тока это не важно.

_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
Миша
Алиас таблицы (с чем его едят): нужен для того, чтобы в пределах одного запроса, обращаться к таблице по другому имени.

Нужно это для именования подзапросов и в целях многократного использования одной и той же таблицы в одном запросе.

Вот если бы не сказали, я бы не знал его названия и не смог загуглить smile.gif

_____________
Принимаю заказы, писать в ЛС
Игорь_Vasinsky
Цитата
нужен для того, чтобы в пределах одного запроса, обращаться к таблице по другому имени.
[quote]

угу.

можно и для полей тоже алиасы делать. в синтаксисе предусмотрено ключевое слово AS (как)

select cell as c1, cell2 as c2 from table as t


но AS можно не писать.

_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
sergeiss
Цитата (paul85 @ 6.04.2015 - 10:27)
Почему многократно? Не вижу причин. По какой логике? Я таким запросом сам кое-что выбирал из очень немаленькой таблицы...

Насчет "многократно", наверное, я погорячился немного. Сорри :) Но всё равно сначала будут выбраны все без исключения данные (в подзапросе - а если их там миллион?), а потом только они будут группироваться. Нарушение здравого смысла (сути использования БД) происходит по-любому. Да, согласен, что для небольшого количества данных так можно сделать. Когда заранее известно, что данных немного будет.


Медведь, мой запрос с учетом "утренней поправки" получается такой:
select
id_user,
username,
(
select message from messages m2 where m2.id_user=m1.id_user order by msg_date desc limit 1) as msg,
msg_date
from messages m1
group by id_user


Тут происходит следующее.
1. Делается выборка уникальных юзеров (группировка по id_user).
2. В каждой строке делается подзапрос: выбираем единственное значение из поля "сообщение", при этом из внешнего запроса передаем m1.id_user во внутренний запрос, где используем его для фильтрации m2.id_user=m1.id_user. Это позволяет выбрать все сообщения именно того юзера, чьи данные у нас имеются в строке внешнего запросе. Также во внутреннем запросе за счет сортировки будет поднята наверх запись с самой последней датой. И за счет ЛИМИТа бы возьмем только одну запись. Из которой выделим поле message и вернем его во внешний запрос. Где ему присвоим алиас msg. Всё, готово :) На самом деле, это всё весьма просто.


Что касается запроса с JOIN, то он мне не нравится :) В немалой степени потому, что там заложено, что возрастание даты на 100% соответствует возрастанию id. А это может быть не совсем так. И тогда запрос получается не верный. И самое главное, что он изначально СЕМАНТИЧЕСКИ не верный, т.к. если речь идет о "последней дате", то и надо дату использовать.
Хотя, конечно, по сути этот запрос близок к тому, что у меня написано. Но он менее гибкий, на мой взгляд.

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
Миша
Вот немного изменил запрос Что скажите про запрос :Kusss

_____________
Принимаю заказы, писать в ЛС
Миша

Насколько жизнеспособен такой запрос:

SELECT * 
FROM
(SELECT * FROM `table` ORDER BY `id` DESC ) AS orderTable
GROUP BY `id_user`


Сначала сортируем по id сообщения (или дате), а потом группируем.

_____________
Принимаю заказы, писать в ЛС
S.Chushkin
Нинасколько.
mySQL позволяет использовать поля не включённые в group by, но не гарантирует, что полученные значения будут из одной строки. В доке об этом написано.
Т.е. в данном случае, для id_user значения будут правильные, значения остальных полей будут "от балды".

_____________
Рекламка / ad.pesow.com Хрень / mr-1.ru
sergeiss
Цитата (Медведь @ 7.04.2015 - 10:39)
Насколько жизнеспособен такой запрос:

Ты словами распиши, что делает этот запрос. Примерно также, как я чуть ранее в этой теме расписал smile.gif И тогда ты поймешь, что делает твой запрос и насколько это не соответствует твоим ожиданиям.

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
Миша
Цитата (sergeiss @ 7.04.2015 - 21:47)
Цитата (Медведь @ 7.04.2015 - 10:39)
Насколько жизнеспособен такой запрос:

Ты словами распиши, что делает этот запрос. Примерно также, как я чуть ранее в этой теме расписал smile.gif И тогда ты поймешь, что делает твой запрос и насколько это не соответствует твоим ожиданиям.

Сортируем в обратном порядке, потом группируем. Вот и получается одно сообщение каждого пользователя с конца. Но S.Chushkin уже объяснил, что значения могут быть не из одной строки. (Такой запрос кстати работает) Но это уже не важно мне нужно решить вопрос из другой темы из этой. Там немного другая таблицы и запрос посложнее будет.

_____________
Принимаю заказы, писать в ЛС
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.