избавится от вложенного запроса
Код:
|wid|uid|
Код:
|from|to|type|
с виду задача простая, но есть одно но
в таблице блокировок записи имеют еще и тип
например блокироваться могут как пользователи, так и группы
и может возникнуть конфликт вида:
Код:
|from|to |type|
|123 |555|group|
|123 |555|user|
|123 |555|group|
|123 |555|user|
Код:
SELECT
*
FROM
`watchers`
LEFT JOIN
`blocked`
ON `wid` = `to`
WHERE
`uid` = 12345 AND
(
`type` IS NULL OR
`type` != 'user'
);
*
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
);
*
FROM
`watchers`
WHERE
`uid` = 12345 AND
`wid` NOT IN (
SELECT
`to`
FROM
`blocked`
WHERE
`type` = 'user' AND
`from` = 12345
);
PS: всего 5 типов блокировок и потому создание для каждой отдельной таблици не оптимально
Код:
SELECT `watchers`.* FROM `watchers`
LEFT JOIN `blocked` ON `wid` = `to` AND `type` = 'user'
WHERE `uid` = 12345 AND `type` IS NULL;
LEFT JOIN `blocked` ON `wid` = `to` AND `type` = 'user'
WHERE `uid` = 12345 AND `type` IS NULL;
но правда этот вариант не работает в случае если в таблице блокировок есть запись о блокировке других наблюдателей
эта проблема решается дополнительной проверкой поля 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
);
*
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
);
Код:
SELECT
*
FROM
`watchers`
LEFT JOIN
`blocked`
ON
`wid` = `to` AND
`uid` = `from` AND
`type` = 'user'
WHERE
`uid` = 12345 AND
`type` IS NULL;
*
FROM
`watchers`
LEFT JOIN
`blocked`
ON
`wid` = `to` AND
`uid` = `from` AND
`type` = 'user'
WHERE
`uid` = 12345 AND
`type` IS NULL;