Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

избавится от вложенного запроса

312
28 ноября 2012 года
dead_star
392 / / 26.11.2006
есть таблица с наблюдателями watchers:

 
Код:
|wid|uid|
и таблица с блокировками blocked:

 
Код:
|from|to|type|
нужно выбрать всех наблюдателей которых нет в таблице блокировок
с виду задача простая, но есть одно но
в таблице блокировок записи имеют еще и тип
например блокироваться могут как пользователи, так и группы
и может возникнуть конфликт вида:

 
Код:
|from|to |type|
|123 |555|group|
|123 |555|user|
таким образом запрос с LEFT JOIN вернет не тот результат который от него ожидают

Код:
SELECT
    *
FROM
    `watchers`
LEFT JOIN
    `blocked`
    ON `wid` = `to`
WHERE
    `uid` = 12345 AND
    (
        `type` IS NULL OR
        `type` != 'user'
    );
спасает только вложенный запрос

Код:
SELECT
    *
FROM
    `watchers`
WHERE
    `uid` = 12345 AND
    `wid` NOT IN (
        SELECT
            `to`
        FROM
            `blocked`
        WHERE
            `type` = 'user' AND
            `from` = 12345
    );
вопрос, можно ли как ни будь избавится от этого вложенного запроса

PS: всего 5 типов блокировок и потому создание для каждой отдельной таблици не оптимально
341
28 ноября 2012 года
Der Meister
874 / / 21.12.2007
 
Код:
SELECT `watchers`.* FROM `watchers`
    LEFT JOIN `blocked` ON `wid` = `to` AND `type` = 'user'
WHERE `uid` = 12345 AND `type` IS NULL;
312
28 ноября 2012 года
dead_star
392 / / 26.11.2006
спасибо большо,
но правда этот вариант не работает в случае если в таблице блокировок есть запись о блокировке других наблюдателей
эта проблема решается дополнительной проверкой поля from

Код:
SELECT
    *
FROM
    `watchers`
LEFT JOIN
    `blocked`
    ON
        `wid` = `to` AND
        `type` = 'user'
WHERE
    `uid` = 12345 AND
    `type` IS NULL AND
    (
        `from` IS NULL OR
        `from` != 12345
    );
312
28 ноября 2012 года
dead_star
392 / / 26.11.2006
даже правильней будет так

Код:
SELECT
    *
FROM
    `watchers`
LEFT JOIN
    `blocked`
    ON
        `wid` = `to` AND
        `uid` = `from` AND
        `type` = 'user'
WHERE
    `uid` = 12345 AND
    `type` IS NULL;
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог