[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Запрос с обьединением 3 таблиц... подскажите
Renden
Что-то я туплю толи понедельник, толи незнаю как сделать.
Задача:
1) Нужно вывести всех пользователей из users.
2) Связать юзера с каникулами holiday.
3) Связать статус users_status с holiday в котором status_id равен hol_status
4) В holiday смотреть попадает ли сегодняшний день в дату начала и дату конца.

Собственно написал такой запрос, но условие WHERE в нем режет вывод всех пользователей из users (т.е данный запрос выводит только тех юзеров у которых условие проходит), а мне нужно чтоб ничего не резало чтоб просто строка status_name была пустой если условие не срабатывает.

SELECT users.`lastname`,users.`firstname`,users_status.`status_name`
FROM `users`
JOIN `users_status`
LEFT JOIN `holiday`
ON users_status.`status_id` = holiday.`hol_status`
AND users.`id` = holiday.`user_id`
WHERE holiday.`date_begin` <= CURDATE() and holiday.`date_end` >= CURDATE()

ЗЫ поставил кавычки для наглядности :)
ЗЫЫ может плохо обьяснил, задайте наводящий вопрос если непонятно что-то.



Спустя 4 минуты, 47 секунд (16.05.2011 - 14:31) sharki написал(а):
Попробуй поиграться с FULL JOIN и RIGHT JOIN

Спустя 8 минут, 36 секунд (16.05.2011 - 14:40) Renden написал(а):
sharki
А чем мне это поможет? Я думаю тут скобки нужны наверно чтоб он сначала выполнил условие, а потом связал..

Спустя 15 минут, 28 секунд (16.05.2011 - 14:55) sharki написал(а):
Щас тоже писал запрос на кол-во, чтобы выводило всё и вся. Чтобы работало, надо сгруппировать по таблице users,

SELECT users.`lastname`,users.`firstname`,users_status.`status_name`
FROM `users`
JOIN `users_status`
LEFT JOIN `holiday`
ON users_status.`status_id` = holiday.`hol_status`
AND users.`id` = holiday.`user_id`
WHERE holiday.`date_begin` <= CURDATE() and holiday.`date_end` >= CURDATE()
GROUP BY `users`.`id`


Попробуй. И так же можешь поиграться с этим же group by с другими таблицами, метод тыка спасет мир)))

Спустя 17 минут, 16 секунд (16.05.2011 - 15:12) Renden написал(а):
sharki
К сожалению ничего не меняется, я непонимаю как GROUP BY спасет, если стоит условие которое убивает все результаты которые по нему не проходят..

Чтоб было проще есть 2 запроса:
вывод всех пользователей
Пример:
1 |Вася | Пупкин
2 |Петя | Васечкин

SELECT `id`,`firstname`, `lastname` FROM `users`

Вывод id пользователя и его статус
Пример:
2 | Отпуск

SELECT holiday.`user_id`,users_status.`status_name`
FROM `users_status`
LEFT JOIN `holiday`
ON users_status.`status_id` = holiday.`hol_status`
WHERE holiday.`date_begin` <= CURDATE() AND holiday.`date_end` >= CURDATE()

Нужно чтоб был 1 запрос где users.id = holiday.user_id
Должно быть:
1 |Вася | Пупкин | null
2 | Петя | Васечкин | Отпуск

Спустя 53 секунды (16.05.2011 - 15:13) Gradus написал(а):
чесно говоря лень во всём этом разбиратся и переписывать, но если срочно надо попробуйте так :)

SELECT users.`lastname`,users.`firstname`,
IF (holiday.`date_begin` <= CURDATE() and holiday.`date_end` >= CURDATE() , users_status.`status_name`,'') AS status_name
FROM `users`
JOIN `users_status`
LEFT JOIN `holiday`
ON users_status.`status_id` = holiday.`hol_status`
AND users.`id` = holiday.`user_id`

и почему нельзя в php проверять ?)

Спустя 2 минуты, 32 секунды (16.05.2011 - 15:16) sharki написал(а):
Renden
Почитай про что я тебе говорил еще в моем первом посте. Чтобы выводило NULL и т.п
http://anton-pribora.ru/articles/mysql/mysql-join/

Спустя 4 минуты, 57 секунд (16.05.2011 - 15:21) Renden написал(а):
Gradus
Ого, почти то, работает но вывод какой-то странный, почемуто каждый юзверь выводиться по 7-8 раз))
А если много записей, нафига грузить все записи в php там его циклом разбирать и проверять есть что или нету.. смысл?

Спустя 4 минуты, 3 секунды (16.05.2011 - 15:25) ИНСИ написал(а):
Renden попробуй так:
mysql_query("
SELECT `u`.*, `h`.*
FROM `users` AS `u`
LEFT JOIN `holiday` AS `h`
ON `h`.`user_id` = `u`.`id`
WHERE `h`.`date_begin` <= CURDATE() AND `h`.`date_end` >= CURDATE()
"
)

Спустя 9 минут, 30 секунд (16.05.2011 - 15:34) Renden написал(а):
velbox
Вывод аналогичен моему запросу тоесть выводятся только те юзеры у которых есть статус, у которых нет не выводятся, а нужно чтоб выводились все..

Спустя 18 минут, 39 секунд (16.05.2011 - 15:53) Gradus написал(а):
только не кидайте помидорами, не охото разбираться в таблицах ))

SELECT DISTINCT `users`.`id` , users.`lastname`,users.`firstname`,
IF (holiday.`date_begin` <= CURDATE() and holiday.`date_end` >= CURDATE() , users_status.`status_name`,'') AS status_name
FROM `users`
JOIN `users_status`
LEFT JOIN `holiday`
ON users_status.`status_id` = holiday.`hol_status`
AND users.`id` = holiday.`user_id`


Спустя 3 минуты, 52 секунды (16.05.2011 - 15:57) Renden написал(а):
Gradus
Помидорка полетела... шучу:)) Ругается на DISTINCT users.`id` хоть и в таблице юзерс есть поле id

Спустя 6 минут, 21 секунда (16.05.2011 - 16:03) Gradus написал(а):
Renden, а сейчас ?) я DISTINCT так ни когда не использвал smile.gif
p.s. переписал выше запрос

Спустя 8 минут, 54 секунды (16.05.2011 - 16:12) Renden написал(а):
Gradus
ООО, почти-почти) Выводится почти как надо, только он если есть опуск то выводит 2 раза этого юзера, 1 раз без статуса, 2 раз со статусом т.е

1 |Вася | Пупкин |
2 | Петя | Васечкин |
2 | Петя | Васечкин | Отпуск
3 Кто-то еще

Спустя 4 минуты, 40 секунд (16.05.2011 - 16:17) ИНСИ написал(а):
Renden тогда можно и так попробовать:

$row = mysql_query("
SELECT `u`.*, `h`.*
FROM `users` AS `u`
LEFT JOIN `holiday` AS `h`
ON `h`.`user_id` = `u`.`id` AND `h`.`date_begin` <= CURDATE() AND `h`.`date_end` >= CURDATE()
"
)

while($data = mysql_fetch_assoc($row)) {
if(isset($data['hol_status']))
echo 'THIS USER ON HOLIDAY - ' . $data['firstname'];
}


То есть, просто получается ты проверяешь на существование определенного поля в таблице hilodays. Если есть, значит чел нашелся в holidays и он отдыхает :)

Спустя 2 минуты, 56 секунд (16.05.2011 - 16:20) Gradus написал(а):
посмотрел, DISTINCT не работает как я хотел smile.gif значит опадает)
Цитата
А если много записей, нафига грузить все записи в php там его циклом разбирать и проверять есть что или нету.. смысл?

IF (holiday.`date_begin` <= CURDATE() and holiday.`date_end` >= CURDATE() , users_status.`status_name`,'') AS status_name - это тоже самое

Спустя 59 секунд (16.05.2011 - 16:21) Renden написал(а):
velbox
Ххыхыхы) Еслиб было все так просто яб так и сделал, так у него там могут быть, отпуск, командировка, больничный, прогул, воспаление хитрости и тп, и этот статус нужно вывести рядом с именем и фамилией сотрудника))

Gradus
Нее, мы получаем данные уже такие какие они нужны для вывода. в этом +, ктомуж в holidays там у 1 человека может быть 100 проставленных статусов(ввиде дат), а может и больше, а терь представь что 100 пользоваетелей хотяб, в память много тащицо будет.

Спустя 40 минут, 25 секунд (16.05.2011 - 17:01) Gradus написал(а):
а я вроде понял что нужно) попробуй что-то типо этого
SELECT users.`lastname`,users.`firstname`,users_status.`status_name`
FROM `users`
JOIN `users_status`
LEFT JOIN `holiday`
ON users_status.`status_id` = holiday.`hol_status`
AND users.`id` = holiday.`user_id`
AND (holiday.`date_begin` <= CURDATE() and holiday.`date_end` >= CURDATE() )

Спустя 28 минут, 39 секунд (16.05.2011 - 17:30) Renden написал(а):
Gradus
Не это совершенно не то что нужно smile.gif На сегодня рабочий день кончился, завтра буду думать по новой)

Спустя 16 часов, 23 минуты, 15 секунд (17.05.2011 - 09:53) Renden написал(а):
Нде.. все утро мучаюсь всеравно нифига не выходит.. знатоки мб кто-нибудь подскажет?)
Быстрый ответ:

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