Харьков Форум
  Харьков Форум > Hi-Tech... > Программирование и создание сайтов

Старый 26.02.2011, 10:51   #1
StyleT

 
 
Регистрация: 11.06.2009
Адрес: Харьков
Сообщений: 424
 
По умолчанию MySQL выборка из двух таблиц с сортировкой

Привет форумчане, возникла необходимость делать поиск по пользователям сайта и выводить юзеров онлайн в начале результатов и вторично сортировать по полю degree. Как организовать выборку одним запросом.

Выборка юзеров из БД:
SELECT id FROM my_users ORDER BY degree DESC LIMIT 0, 30

Выборка юзеров онлайн
SELECT id FROM users_session WHERE guest='0' AND client_id='0'

Нужно выдать отсортированные id, в двух таблицах они совпадают, однако в таблице users_session записи лишь юзеров онлайн. Как совместить эти 2 запроса?


__________________
Мысли глобально, действуй локально.
    Вверх
Старый 26.02.2011, 12:00   #2
ChuguevMan


 
 
Регистрация: 12.07.2010
Сообщений: 1,727
 
По умолчанию
select sess.id from
(SELECT id FROM my_users ORDER BY degree DESC LIMIT 0, 30) as my
inner join
(SELECT id FROM users_session a sess WHERE guest='0' AND client_id='0') as sess
on my.id=sess.id


    Вверх
Старый 26.02.2011, 12:11   #3
StyleT

 
 
Регистрация: 11.06.2009
Адрес: Харьков
Сообщений: 424
 
По умолчанию
Цитата:
Сообщение от ChuguevMan
select sess.id from
(SELECT id FROM my_users ORDER BY degree DESC LIMIT 0, 30) as my
inner join
(SELECT id FROM users_session a sess WHERE guest='0' AND client_id='0') as sess
on my.id=sess.id
а что означает sess? не понял смысл сего выражения, и БД ругается


__________________
Мысли глобально, действуй локально.
    Вверх
Старый 26.02.2011, 12:15   #4
ChuguevMan


 
 
Регистрация: 12.07.2010
Сообщений: 1,727
 
По умолчанию
Извиняюсь, тачпад выделывается, вот так нужно:

select sess.id from
(SELECT id FROM my_users ORDER BY degree DESC LIMIT 0, 30) as my
inner join
(SELECT id FROM users_session WHERE guest='0' AND client_id='0') as sess
on my.id=sess.id


    Вверх
Старый 26.02.2011, 12:21   #5
StyleT

 
 
Регистрация: 11.06.2009
Адрес: Харьков
Сообщений: 424
 
По умолчанию
Цитата:
Сообщение от ChuguevMan
Извиняюсь, тачпад выделывается, вот так нужно:

select sess.id from
(SELECT id FROM my_users ORDER BY degree DESC LIMIT 0, 30) as my
inner join
(SELECT id FROM users_session WHERE guest='0' AND client_id='0') as sess
on my.id=sess.id
смог исполнить запрос, но вот он ничего не вернул

Решил проблему вот так
SELECT id
FROM my_users
ORDER BY id
IN (

SELECT id
FROM users_session
WHERE guest = '0'
AND client_id = '0'
) DESC , degree DESC
LIMIT 0 , 30


__________________
Мысли глобально, действуй локально.
    Вверх
Старый 26.02.2011, 12:22   #6
AS0kol


 
 
Регистрация: 12.07.2010
Адрес: Харьков
Сообщений: 1,270
 
По умолчанию
Цитата:
Сообщение от ChuguevMan
Извиняюсь, тачпад выделывается, вот так нужно:

select sess.id from
(SELECT id FROM my_users ORDER BY degree DESC LIMIT 0, 30) as my
inner join
(SELECT id FROM users_session WHERE guest='0' AND client_id='0') as sess
on my.id=sess.id

Феерично.


    Вверх
Старый 26.02.2011, 12:24   #7
ChuguevMan


 
 
Регистрация: 12.07.2010
Сообщений: 1,727
 
По умолчанию
Цитата:
Сообщение от StyleT
смог исполнить запрос, но вот он ничего не вернул

Решил проблему вот так
SELECT id
FROM my_users
ORDER BY id
IN (

SELECT id
FROM users_session
WHERE guest = '0'
AND client_id = '0'
) DESC , degree DESC
LIMIT 0 , 30
Конечно не вернул - обрати внимание где рубиться запрос первый - убери оттуда LIMIT 0 , 30 и поставь как у себя в конец.


    Вверх
Старый 26.02.2011, 12:47   #8
Klez


 
 
Регистрация: 14.06.2007
Адрес: Оттуда
Сообщений: 13,640
 
По умолчанию
Код:
SELECT
      mu.[id]
   FROM
      [my_users] as mu
   INNER JOIN
      [users_session] as us
   ON
      mu.[id]=us.[id]
   WHERE
      us.[guest]='0'
      AND
      us.[client_id]='0'
   ORDER BY
      us.[degree] DESC 
   LIMIT 0, 30


__________________
° 。 ° ˚* _Π____*
˚ ˛ •˛•*/____ /~\
˚ ˛ •˛• | 田 田 |門|
    Вверх
Старый 26.02.2011, 13:01   #9
StyleT

 
 
Регистрация: 11.06.2009
Адрес: Харьков
Сообщений: 424
 
По умолчанию
Цитата:
Сообщение от ChuguevMan
Конечно не вернул - обрати внимание где рубиться запрос первый - убери оттуда LIMIT 0 , 30 и поставь как у себя в конец.
убрал, вернуло только id юзеров онлайн


__________________
Мысли глобально, действуй локально.
    Вверх
Старый 26.02.2011, 13:43   #10
Klez


 
 
Регистрация: 14.06.2007
Адрес: Оттуда
Сообщений: 13,640
 
По умолчанию
Цитата:
Сообщение от StyleT
убрал, вернуло только id юзеров онлайн
а тебе что надо? Кстати у тебя путаница в именах полей. Рекомендую не использовать имена вроде "id", в каждой таблице есть id, и ты потом хуй разберешь где какой id и на какой id он ссылается. Дописывай к имени ключевого поля имя таблицы, например user_id, session_id. Тогда ты легко поймешь, где ключ, где ссылка на ключ


__________________
° 。 ° ˚* _Π____*
˚ ˛ •˛•*/____ /~\
˚ ˛ •˛• | 田 田 |門|
    Вверх
Старый 26.02.2011, 13:45   #11
StyleT

 
 
Регистрация: 11.06.2009
Адрес: Харьков
Сообщений: 424
 
По умолчанию
Цитата:
Сообщение от Klez
а тебе что надо? Кстати у тебя путаница в именах полей
всех но онлайн в первую очередь


__________________
Мысли глобально, действуй локально.
    Вверх
Старый 26.02.2011, 14:21   #12
Klez


 
 
Регистрация: 14.06.2007
Адрес: Оттуда
Сообщений: 13,640
 
По умолчанию
ну тогда можно так:
Код:
SELECT
		mu.[id] as [user_id], 
		(CASE WHEN us.[id] IS NULL THEN 0 ELSE 1 END) AS [is_online_flg]
	FROM
		[my_users] as mu
	LEFT OUTER JOIN
		[users_session] as us
	ON 
		mu.[id]=us.[id] 
		AND 
		us.[guest]='0' 
		AND 
		us.[client_id]='0'
	ORDER BY
		[is_online_flg] DESC,
		us.[degree] DESC


__________________
° 。 ° ˚* _Π____*
˚ ˛ •˛•*/____ /~\
˚ ˛ •˛• | 田 田 |門|
    Вверх
Старый 26.02.2011, 15:33   #13
HelloWorld

 
Регистрация: 3.12.2009
Сообщений: 164
 
По умолчанию
джоины, джоины.. а чего не union. есть два запроса, результаты нужно последовательно объединить в один большой результат, по-моему union выглядит вполне естественно.

поведение union-а я рассматриваю MySQL-ное. для начала можно просто им соединить два запроса ТС-а. всё будет классно, сначала пойдут онлайн, потом все остальные (повторяющиеся id будут выкинуты, так как UNION работает по дефолту как UNION DISTINCT) только ничего не отсортируется по degree, т.к.
Цитата:
use of ORDER BY for individual SELECT statements implies nothing about the order in which the rows appear in the final result because UNION by default produces an unordered set of rows
и вообще
Цитата:
If ORDER BY appears without LIMIT in a SELECT, it is optimized away because it will have no effect anyway.
поэтому придется немного извратиться

Код:
SELECT * FROM 
(
    (SELECT id, 1 AS is_online, 0 AS deg FROM users_session WHERE guest='0'  AND client_id='0')
    UNION 
    (SELECT id, 0 AS is_online, degree AS deg FROM my_users ORDER BY degree DESC LIMIT 0, 30)
) result_table 
GROUP BY id 
ORDER BY is_online DESC, deg
правда, онлайн юзеры не будут отсортированы по degree, но запрос ТС-а по онлайн-юзерам тоже этого не делал.. если это нужно, можно немного переделать SELECT по users_session
ПС если нужны только id, в общем SELECT-е * можно заменить на id, просто так по результатам видно, как это всё работает


    Вверх
Старый 26.02.2011, 18:29   #14
StyleT

 
 
Регистрация: 11.06.2009
Адрес: Харьков
Сообщений: 424
 
По умолчанию
Цитата:
Сообщение от HelloWorld
джоины, джоины.. а чего не union. есть два запроса, результаты нужно последовательно объединить в один большой результат, по-моему union выглядит вполне естественно.

поведение union-а я рассматриваю MySQL-ное. для начала можно просто им соединить два запроса ТС-а. всё будет классно, сначала пойдут онлайн, потом все остальные (повторяющиеся id будут выкинуты, так как UNION работает по дефолту как UNION DISTINCT) только ничего не отсортируется по degree, т.к. и вообще
поэтому придется немного извратиться

Код:
SELECT * FROM 
(
    (SELECT id, 1 AS is_online, 0 AS deg FROM users_session WHERE guest='0'  AND client_id='0')
    UNION 
    (SELECT id, 0 AS is_online, degree AS deg FROM my_users ORDER BY degree DESC LIMIT 0, 30)
) result_table 
GROUP BY id 
ORDER BY is_online DESC, deg
правда, онлайн юзеры не будут отсортированы по degree, но запрос ТС-а по онлайн-юзерам тоже этого не делал.. если это нужно, можно немного переделать SELECT по users_session
ПС если нужны только id, в общем SELECT-е * можно заменить на id, просто так по результатам видно, как это всё работает
я допилил немного свой запрос и он сортирует онлайн по degree это важно если их >5, а потом ещё определение для каждого, онлайн/не онлайн, получилось не очень красиво на мой взгляд, но лучше я не нашел да и не оч. хотел


__________________
Мысли глобально, действуй локально.
    Вверх
Старый 26.02.2011, 18:32   #15
Therion

 
 
Регистрация: 1.12.2007
Адрес: volatile
Сообщений: 726
 
По умолчанию
Код:
SELECT 
	users.id, users.degree, IF(sessions.uid, 1, 0) AS online
FROM
	users
	LEFT OUTER JOIN sessions ON sessions.uid=users.id AND sessions.guest='0' AND sessions.client_id='0'
ORDER BY online DESC, degree DESC;
как-то так

а блин... klez уже написал


__________________
Мужик сказал, мужик забыл, мужику напомни, мужик в aхуe.
    Вверх
Старый 26.02.2011, 18:33   #16
StyleT

 
 
Регистрация: 11.06.2009
Адрес: Харьков
Сообщений: 424
 
По умолчанию
Цитата:
Сообщение от Therion
Код:
SELECT 
	users.*, IF(sessions.uid, 1, 0) AS online
FROM
	users
	LEFT JOIN sessions ON sessions.uid=users.id
WHERE 1
ORDER BY online DESC, degree DESC;
как-то так
а можно узнать куда впихнуть WHERE guest='0' AND client_id='0' так как простого нахождения в таблице sessions недостаточно для определения юзера как онлайн, я нуб в SQL


__________________
Мысли глобально, действуй локально.
    Вверх
Старый 26.02.2011, 18:34   #17
Therion

 
 
Регистрация: 1.12.2007
Адрес: volatile
Сообщений: 726
 
По умолчанию
Цитата:
Сообщение от StyleT
а можно узнать куда впихнуть WHERE guest='0' AND client_id='0' так как простого нахождения в таблице sessions недостаточно для определения юзера как онлайн, я нуб в SQL
уже исправил, см. выше


__________________
Мужик сказал, мужик забыл, мужику напомни, мужик в aхуe.
    Вверх
Старый 26.02.2011, 18:42   #18
StyleT

 
 
Регистрация: 11.06.2009
Адрес: Харьков
Сообщений: 424
 
По умолчанию
Цитата:
Сообщение от Therion
уже исправил, см. выше
ща затестю, он намного лучше того говна что сочинил я

Цитата:
Сообщение от Therion
уже исправил, см. выше
пашет, спасибо огромное надо будет подучить SQL


__________________
Мысли глобально, действуй локально.
    Вверх
Старый 26.02.2011, 18:49   #19
Therion

 
 
Регистрация: 1.12.2007
Адрес: volatile
Сообщений: 726
 
По умолчанию
Цитата:
Сообщение от StyleT
ща затестю, он намного лучше того говна что сочинил я



пашет, спасибо огромное надо будет подучить SQL
Да не за что,
Klez еще днем написал то же самое, для MSSQL


__________________
Мужик сказал, мужик забыл, мужику напомни, мужик в aхуe.
    Вверх
Старый 28.02.2011, 16:09   #20
Тыемураз


 
 
Регистрация: 16.12.2008
Сообщений: 2,129
 
По умолчанию
Цитата:
Сообщение от Klez
Код:
SELECT
      mu.[id]
   FROM
      [my_users] as mu
   INNER JOIN
      [users_session] as us
   ON
      mu.[id]=us.[id]
   WHERE
      us.[guest]='0'
      AND
      us.[client_id]='0'
   ORDER BY
      us.[degree] DESC 
   LIMIT 0, 30
Добрый день.
Половина слушателей ответили,что под два лежачих камня вода не потечет,49 % слушателей ответили,что вода накроет их ,и лишь один слушатель ответил,что вода будет течь под камнями,создовая гнездышко под этап для речной форельки.


__________________
Пока все хорошо.
Снег идет прямо на крыши .Мороз .
    Вверх

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Харьков Форум > Hi-Tech... > Программирование и создание сайтов

Быстрый переход


Часовой пояс GMT +2, время: 05:23.


Харьков Форум Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.