|
|
|
| В таблице Friends есть такие поля:
Friend1 (int) Friend2 (int) is_friend (int)
Коля Маша 2
Вика Коля 2
Маша Женя 2
Дима Маша 2
Артем Маша 2
Коля Вася 1
У Коли есть 2 друга: Маша и Вика
У Маши есть 4 друга: Коля, Женя, Дима, Артем
Нужно выбрать друзей и друзей друзей Коли: Маша, Вика, Женя, Дима, Артем.
Подскажите, пожалуйста, как построить такой запрос. | |
|
|
|
|
|
|
|
для: 1prom
(16.06.2009 в 21:13)
| | Если это рабочий вопрос ( а не учебный) таблицу следует перепроектировать. Она явно не нормализована.
Раскройте всю правду о Васе.
>Friend1 (int) Friend2 (int) is_friend (int)
и вправду int... | |
|
|
|
|
|
|
|
для: Trianon
(16.06.2009 в 21:30)
| | Не знаю даже как перепроектировать...
У каждого имени есть свой номер... я для простоты имена поставил.
а Вася он не в друзьях... он как бы еще это не подтвердил от Коли, если подтвердит там будет двоечка :)) | |
|
|
|
|
|
|
|
для: 1prom
(16.06.2009 в 21:42)
| | ну вот Вы пишете "У Маши есть 4 друга: Коля, Женя, Дима, Артем"
а строк с Машей во второй колонке только три. из четырех
а в первой так и вообще одна. | |
|
|
|
|
|
|
|
для: Trianon
(16.06.2009 в 22:08)
| | все правильно, просто Маша добавила в друзья только Женю с его согласия, остальные добавляли ее в друзья с ее согласия. В итоге 4 друга.
Я не знаю просто как мне правильно скомбинировать запрос... | |
|
|
|
|
|
|
|
для: Trianon
(16.06.2009 в 22:08)
| | Trianon, если Вы не подскажете, вряд ли кто-то поможет )) | |
|
|
|
|
|
|
|
для: 1prom
(17.06.2009 в 22:11)
| | Я уже сказал.
Строк с Машей должно быть восемь.
Отношение "друзья" не является симметричным даже в реальной жизни, что уж тут про sql говорить... | |
|
|
|
|
|
|
|
для: Trianon
(17.06.2009 в 22:25)
| | но ведь это лишние записи БД, ладно, проехали,
теперь допустимв нас есть 8 строчек с Машей и 4 с Колей. как же запрос составить?? | |
|
|
|
|
|
|
|
для: 1prom
(17.06.2009 в 22:37)
| | Таблица friend_of(user_id, friend_id)
Запрос показывающий друзей Маши
SELECT friend_id
FROM friend_of
WHERE user_id = $masha
|
Запрос показывающий друзей друзей Маши
SELECT f1.friend_id
FROM friend_of f1
JOIN friend_of f2 ON f1.user_id = f2.friend_id
WHERE f2.user_id = $masha
|
| |
|
|
|
|
автор: 345386876 (27.06.2009 в 02:32) |
|
|
для: Trianon
(17.06.2009 в 23:44)
| | Интересно, а как будет выглядеть подсчёт количества неподтверждённых друзей?
Скажем, какой-то человек пытается добавить меня в друзья. Таким образом добавляется запись
(user_id, friend_id) = (id_этого_пользователя, мой_id)
В свою очередь я должен добавить запись
(user_id, friend_id) = (мой_id, id_этого_пользователя)
, ... чтобы он считался подтвержденным другом.
Было бы достаточно просто, если бы в MySQL был FULL OUTER JOIN. Его, кажется, нет. Чо делать? | |
|
|
|
|
|
|
|
для: 345386876
(27.06.2009 в 02:32)
| | Зарегистрируйтесь, пожалуйста. | |
|
|
|
|
|
|
|
для: Trianon
(27.06.2009 в 02:49)
| | Я неправильно вопрос задал. Вычислить неподтвержденных я знаю как. Как можно достать всех друзуй - неподтверженных и подтвержденных одновременно? То есть какая-то запись может быть у меня, но не быть соответвующией у друга. Аналогично может наооборот. | |
|
|
|
|
|
|
|
для: 32423423
(27.06.2009 в 02:54)
| | Все мои друзья (и подтвержденные и неподтвержденные) характеризуются friend_of.user_id = $my_id
Все Ваши друзья (и подтвержденные и неподтвержденные) характеризуются friend_of.user_id = $your_id
Еще раз . Отношения могут быть рефлексивными , симметричными , транзитивными
Являться другом - отношение нерефлексивное, несимметричное и нетранзитивное.
Поскольку оно несимметричное, прямая и встречная запись в таблице означают разные вещи. Совсем разные.
Да, для симметричных отношений Full outer join могло бы пригодиться.
Но явная декларация таких отношений (без развертывания в пару независимых) приводит к денормализации схемы, а значит к изрядному усложнению логики как запросов, так и приложения.
Т.е. на мой взгляд - ну его нафик.
PS. Спасибо за понимание. Я про логин. | |
|
|
|
|
|
|
|
для: Trianon
(27.06.2009 в 03:05)
| | В моём случае отношение "есть друг" симметричное, антирефлексивное, нетранзитивное. Какая организация предпочтительней-то?..
Из Вашего поста я понимаю так, что симметричность несовместима с организацией, что Вы предложили топикстартеру. А парочка полей "друг_1", "друг_2" приводит к денормализации схемы, а значит к изрядному усложнению логики как запросов.
Выходит, что реализовать симметричность можно только "через задницу"?
В принципе, я могу и парочку полей использовать. Уже так делал ("через задницу"). Просто неудобно. Потому что через задницу. | |
|
|
|
|
|
|
|
для: 32423423
(27.06.2009 в 03:11)
| | по-моему, через задницу будет как раз наоборот устраивать всякое
(SELECT friend_id AS fr FROM friend_of WHERE user_id = $my_id)
UNION
(SELECT user_id AS fr FROM friend_of WHERE friend_id = $my_id)
|
| |
|
|
|
|
автор: 3563649 (27.06.2009 в 03:39) |
|
|
для: Trianon
(27.06.2009 в 03:25)
| | Вот вокруг этого и вертелся! Мне просто необходимо было еще отсеживать кто подал заявку, поэтому почему-то сразу отбрасывал UNION.
Сейчас, думаю, добавить ", -1" и ", 1" к списку выборки, тогда если <0, то я подаю, если ==0, то мы друзья, если >0, то он подает.
Спасибо.
P.S. Я уже с мобилки, поэтому уж извините. | |
|
|
|
|
автор: 396465640 (27.06.2009 в 03:44) |
|
|
для: 3563649
(27.06.2009 в 03:39)
| | Я говорю о SUM + GROUP BY user_id!
P.S. Т.к. я с мобилки то точно не уверен: в GROUP BY надо вроде будет писать именно название столбца из первого Select'а | |
|
|
|
|
|
|
|
для: 396465640
(27.06.2009 в 03:44)
| | Don't worry - be happy! | |
|
|
|