Возможно сделать один запрос?

PRO

Новичок
Возможно сделать один запрос?

Здравствуйте.

Ситуация такая:
есть 3 таблици
users
users_info
users_job

Они все связаны по user_id.
В таблице users_info одному user_id соответствует 1 запись.
В users_job у одного user_id может быть несколько записей.

SELECT users.*,users_info.* FROM users LEFT JOIN users_info ON users_info.user_id=users.id WHERE users.id IN (x,y,z)
SELECT * FROM users_job WHERE user_id=x ORDER BY param1,param2,param3 LIMIT 0,1 (задача выбрать 1 запись изходя из критериев)

Задача совместить 2 запроса в 1.(проблема order и limit не покати)
SELECT users.*,users_info.*,users_job.* ....
чтобы результат был вида:
id1 info1 job1
id2 info2 job2

Возможно ли из всех таблиц выбрать необходимые данные одним запросом?
 

Gas

может по одной?
можно соорудить запросы ради запросов:

1. подзапрос+concat() нужных полей users_job, вариант нормальный, но вот concat...
Кстати, кто как часто такие хаки ставит?

2. [sql]
SELECT users.*,users_info.*, jobs.* FROM users LEFT JOIN users_info ON users_info.user_id=users.id JOIN (SELECT * FROM users_job WHERE user_id=x ORDER BY param1,param2,param3 LIMIT 1) AS jobs ON jobs.user_id=users.id WHERE users.id=x
UNION ... тоже с user.id=Y UNION ...тоже с user.id=Z
[/sql]

конечно не проверял работоспособность :)

о ужас, отформатированный он выглядит вообще огромным
 

asm

Пофигист
ORDER BY param1,param2,param3 LIMIT 1
лимит можно заменить группировкой по user_id например, извесный хак MySQL
 

PRO

Новичок
Насколько я понимаю в mysql сначала будет сделано group, а потом только order.
Т.е эфект будет не тот.
Если я не прав, то поправьте меня пожалуйста.

-~{}~ 11.12.07 13:59:

SELECT users . * , users_info . * , jobs . *
FROM users
LEFT JOIN users_info ON users_info.user_id = users.id LEFT JOIN (SELECT * FROM users_job ORDER BY param1,param2,param3) AS jobs ON jobs.user_id=users.id GROUP BY users.id

Тема закрыта!
 

Gas

может по одной?
Пр таком запросе record set: (SELECT * FROM users_job ORDER BY param1,param2,param3) AS jobs - будет вытянут в temporary table и при джойне с ним никаких ключей использоваться не будет, если данных много - это тормоз.

и кстати задача отличается от исходной, вначале нужно было получить данные только для некоторых пользователей, теперь же выходит что для всех.
 

PRO

Новичок
Задача осталась той-же(добавить IN).
Данные со временем возрастут...
На данный момент релизовал так: для каждого user_id получаю актульный job.
В итоге получается много маленьких запросов(для каждого user_id).
Хотелось бы придумать что-нибудь попроще всмысле реализации..

Может есть еще каки-то идеи или текущий метод самый оптимальный(скорости)?
 

Gas

может по одной?
[SQL]
SELECT t.*, uj.* FROM (
SELECT users . * , users_info . * , (SELECT id FROM users_job WHERE user_id=users.id ORDER BY param1,param2,param3 LIMIT 1) as job_id
FROM users
LEFT JOIN users_info ON users_info.user_id = users.id WHERE user.is IN (...) GROUP BY users.id) AS t
LEFT JOIN users_job AS uj ON uj.id=t.job_id
[/SQL]

это ещё пример, по поводу как можно сделать одним запросом, тут тоже t - temporary table, но она должна быть первой при джойне с uj и потерь быть не должно.

Что касается скорости, тут нужно смотреть explain.
 

PRO

Новичок
EXPLAIN пока не смотрел, но вроде то что доктор прописал.
Спасибо за помощь!

-~{}~ 12.12.07 19:58:

Gas последний вопрос.
Если в users_job нет записей с user_id то этот запрос не покажет юзера.
Как правильно сделать чтобы в такой ситуации стояли просто NULL?
 

Gas

может по одной?
Проверь сам запрос ещё раз, точно стоит left join? У меня подобный запрос работает правильно, null - если нет связи.
 

PRO

Новичок
Извиняюсь.
Я под конкретные нужды перемудрил с запросом.
Все работает правильно.
Еще раз огромное спасибо за помощь :)
 
Сверху