2012-04-17 3 views
1

Позвольте мне сначала задать ситуацию.MySQL-условие SQL. Возможно ли мой сценарий?

У меня есть таблица «пользователей» с полями X, поля не имеют значения для моего вопроса, кроме «видимости». Видимость - это tinyint, а значения означают следующее (0 = видимое для всех, 1 = видимое только для друзей и 2 = невидимое).

У меня также есть стол (id, user_id, target_user_id). user_id является другом с target_user_id. Достаточно легко?

Вот где он становится липким. Im написание PHP API и мой метод класса выглядит вроде как это:

public function getUsers($requester, $page, $num) {} 
  • в $requester это идентификатор пользователя лица, запрашивающего пользователи
  • $page является пагинацией номера страницы
  • $num - количество позиций на странице

Что я хочу делать в SQL, получается, что $num пользователей из таблицы users, если thei r поле видимости = 0 или 1. Если флаг видимости равен 1, мне нужно убедиться, что идентификатор пользователя и запрашивающий $ являются друзьями в таблице друзей и только возвращают этого пользователя, если они являются друзьями.

Я думал об использовании PHP для фильтрации видимости после того, как я верну свои результаты, но разбиение на страницы (ограничение) будет испорчено, если я попрошу, например, 5 записей, и один или несколько пользователей имеют видимость, равную 1, и не друзья с запрашивающим. Это в значительной степени нужно сделать полностью через sql.

Возможна ??

+0

Вы попробовали что-нибудь? это довольно просто ... На самом деле вы сами сделали это условие в своем вопросе, вам просто нужно переписать его на sql –

+1

Возможно, да, есть игра и посмотреть, что вы придумали. Хорошее место для рассмотрения синтаксиса 'WHERE', поскольку все, что вы просите, это' WHERE visibility = 0 OR (visibility = 1 AND somethingToCheckFriends) '. «ЛЕВЫЙ ПРИСОЕДИНЯЙТЕ», скорее всего, тоже будет. Прочитайте их, сделайте некоторые исследования и попробуйте кое-что. –

+0

Для них, чтобы быть друзьями, должна быть запись от А до Б И от Б до А в таблице друзей? – diolemo

ответ

1

Попробуйте создать временную таблицу «Темп» с такой же структурой, как и пользователи.

select * into temp From users where visibility=0 or visibility=1; 
Select * from temp, friends where (temp.visibility=0) or (temp.user_id = friends.target_user_id); 

Не забудьте опорожнить временную таблицу.

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

select * from users, friends where (users.visibility=0) or (users.visibility=1 and users.user_id = friends.target_user_id); 
+0

Это получилось. Я забыл, что могу выбрать из двух разных таблиц. Вот окончательное решение: 'SELECT users. * от пользователей, друзей ГДЕ ( users.visibility = 0 ) ИЛИ ( users.visibility = 1 И ( users.id = friends.user_id И follows.target_user_id = <запросчик идентификатор> ) ) GROUP BY users.id' – pogeybait

0

Я думаю, что вы можете использовать LEFT JOIN для этого .. что-то вроде

"SELECT * 
FROM users t1 
LEFT JOIN friends t2 ON t2.user_id=t1.id AND t1.visibility=1 
INNER JOIN user t3 ON t3.id=t2.target_user_id 
WHERE t1.visibility=0 OR t1.visibility=1 
LIMIT ".($page*$num).",".$num 
+0

Это выглядит близко, но если видимость равна 0, вообще не должно быть никаких объединений. Вот почему я спросил об условных операторах, таких как IF или CASE. У каждого пользователя будет другой флаг видимости, а те, у кого есть 1, должны быть проверены на отношения в таблице друзей. Если эти отношения не существуют, то запись этого пользователя не должна возвращаться. – pogeybait

+0

Это неправильный SQL, но это почти так, как должно быть примерно так: SELECT * FROM пользователей WHERE (видимость = 0 ИЛИ видимость = 1) И (IF (видимость = 1) SELECT * из друзей, где user_id = users.id AND target_user_id = $ requester, TRUE, FALSE) Неверный оператор IF, указанный выше, предназначен для чтения, если видимость равна 1, выполните оператор sql и верните true, если совпадение найдено или false в противном случае. – pogeybait

+0

добавил условие, чтобы левое присоединиться .. может быть, это поможет? –

Смежные вопросы