MySQL выборка из двух таблиц с сортировкой

Статус: Offline
Реєстрація: 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 запроса?
 
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
 
Извиняюсь, тачпад выделывается, вот так нужно:

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 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
 
смог исполнить запрос, но вот он ничего не вернул

Решил проблему вот так
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 и поставь как у себя в конец.
 
Код:
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
 
убрал, вернуло только id юзеров онлайн :(

а тебе что надо? :confused: Кстати у тебя путаница в именах полей. Рекомендую не использовать имена вроде "id", в каждой таблице есть id, и ты потом хуй разберешь где какой id и на какой id он ссылается. Дописывай к имени ключевого поля имя таблицы, например user_id, session_id. Тогда ты легко поймешь, где ключ, где ссылка на ключ
 
ну тогда можно так:
Код:
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
 
джоины, джоины.. а чего не 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, просто так по результатам видно, как это всё работает
 
джоины, джоины.. а чего не 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, а потом ещё определение для каждого, онлайн/не онлайн, получилось не очень красиво на мой взгляд, но лучше я не нашел да и не оч. хотел:D
 
Код:
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 уже написал :)
 
Код:
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 :(
 
Код:
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 % слушателей ответили,что вода накроет их ,и лишь один слушатель ответил,что вода будет течь под камнями,создовая гнездышко под этап для речной форельки.
 
Назад
Зверху Знизу