Пыха всегда с тобой

Добро пожаловать на Пыху!

Логин:
Пароль:
 

Нет прописки? Зарегистрируйся!

Новости

Мы в твиттере!
Мы вконтакте!
Мы на яндексе!

Краснодарское время: 25 Май, 2012, 02:27:54

Страниц: [1]
Печать
Автор Тема: Бутерброд из вложенных запросов, не могу прожевать несколько AND и IN подряд.  (Прочитано 203 раз)
0 Пользователей и 1 Гость смотрят эту тему.
armageddance    ↓ 
03 Август, 2011, 12:50:34
НЕ ХУЕТА! ХУЕТА!

Карма: 0
Сообщений: 29
Сила слова: 0

Помогите разобраться со сложным запросом с большим количеством подзапросов, уже потратил 2 часа и наверное не один день без помощи над ним промучаюсь)
Суть - нужно выбрать все услуги, в которые записан клиент одновременно в определенный промежуток времени.
 
category - таблица услуг: name - название услуги, sid - идентификатор услуги.
sessions - таблица записей: service_id - идентификатор услуги в ней, start_time - время начала оказания услуги, end_time - время окончания оказания услуги, session_id - идентификатор записи.
client_sessions - таблица связи клиентов и записей. client_id - идентификатор клиента, session_id - идентификатор записи.
 
SQL
SELECT name FROM category WHERE sid IN
                (
                      SELECT DISTINCT service_id FROM sessions WHERE session_id IN
                      (
                                      SELECT session_id FROM sessions WHERE
                                    (
                                                (
                                                    start_time<=(SELECT start_time FROM sessions WHERE session_id='$session_id')
                                                          AND end_time>=(SELECT start_time FROM sessions WHERE session_id='$session_id')
                                                )
                                                OR
                                                (
                                                    start_time<=(SELECT end_time FROM sessions WHERE session_id='$session_id')
                                                          AND end_time>=(SELECT end_time FROM sessions WHERE session_id='$session_id')
                                                )
                                                OR
                                                (
                                                    start_time>=(SELECT start_time FROM sessions WHERE session_id='$session_id')
                                                          AND end_time<=(SELECT end_time FROM sessions WHERE session_id='$session_id')
                                                )
                                                OR
                                                (
                                                    start_time<=(SELECT start_time FROM sessions WHERE session_id='$session_id')
                                                          AND end_time>=(SELECT end_time FROM sessions WHERE session_id='$session_id')
                                                )
                                     )
                     )
                     AND session_id<>'$session_id'
                     AND session_id IN
                     (
                                    SELECT session_id FROM client_sessions WHERE client_id='$client_id'
                     )
 
                )
Вот такой запрос возвращает какие-то услуги, но не те, какие нужно вернуть, что-то у него с логикой (со скобками) не так....
Записан
AlexB    ↓ 
03 Август, 2011, 12:58:19 , спустя 7 минут 45 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: в ухо

Карма: 89
Сообщений: 3426
Сила слова: 2.6

Я не понял, а нафига третья таблица?
Что мешает в sessions сразу id клиента писать?
Спустя 1 минуту 47 секунд добавил
И еще, открой для себя JOIN
Записан

armageddance    ↓ 
03 Август, 2011, 01:03:04 , спустя 4 минуты 45 секунд
НЕ ХУЕТА! ХУЕТА!

Карма: 0
Сообщений: 29
Сила слова: 0

ТО есть, берем $session_id, определяем у нее start_time и end_time, определяем те записи, какие пересекаются по времени с текущей, сравниваем с теми session_id, на которые записан текущий клиент client_id, отнимаем из полученного списка текущую session_id (мы ее итак знаем) и выдаем названия услуг name, на которые есть запись по всем найденным session_id
Спустя 1 минуту 56 секунд добавил

Я не понял, а нафига третья таблица?
Что мешает в sessions сразу id клиента писать?
Спустя 1 минуту 47 секунд добавил
И еще, открой для себя JOIN
Дело в том, что клиентов может быть несколько в одной записи. Групповые записи на услуги. То есть тут связь один ко многому, поэтому заведена таблица client_sessions.
Записан
AlexB    ↓ 
03 Август, 2011, 01:19:10 , спустя 16 минут 6 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: в ухо

Карма: 89
Сообщений: 3426
Сила слова: 2.6

SELECT
C.Name
FROM
category as C
JOIN sessions as S ON S.sid = C.session_id
JOIN client_sessions as CS USING (session_id)
WHERE
CS.cient_id = ид клиента AND здесь условие на пересечение промежутков времени, сам пиши мне лень
 
Что-то типа такого, я не отлаживал, главное показал тебе как JOIN работает
Записан

armageddance    ↓ 
03 Август, 2011, 01:45:13 , спустя 26 минут 3 секунды
НЕ ХУЕТА! ХУЕТА!

Карма: 0
Сообщений: 29
Сила слова: 0

Разобрался, все правильно на самом деле.
Только два последних OR в проверке пересечений - лишние. Надо так:
 
(
                          start_time<=(SELECT start_time FROM sessions WHERE session_id='$session_id')
                                   AND end_time>=(SELECT start_time FROM sessions WHERE session_id='$session_id')
                          )
OR
                          (
                          start_time<=(SELECT end_time FROM sessions WHERE session_id='$session_id')
                                   AND end_time>=(SELECT end_time FROM sessions WHERE session_id='$session_id')
                           )
Спустя 1 минуту 40 секунд добавил

SELECT
C.Name
FROM
category as C
JOIN sessions as S ON S.sid = C.session_id
JOIN client_sessions as CS USING (session_id)
WHERE
CS.cient_id = ид клиента AND здесь условие на пересечение промежутков времени, сам пиши мне лень
 
Что-то типа такого, я не отлаживал, главное показал тебе как JOIN работает
Да, в такой форме запрос намного изящнее и проще выглядит, спасибо, поправлю...
Записан
phpdude    ↓ 
03 Август, 2011, 02:25:47 , спустя 40 минут 34 секунды
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 345
Сообщений: д-о-х-у-я!
Сила слова: 1.66

Да, в такой форме запрос намного изящнее
изящнее запрос .. эх! он мне уже нравится!
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
Страниц: [1]
Печать
 

Перейти в:  

Этот топик скрыли: NRG, adw0rd