|
|
|
| Есть таблица users. Там некоторая инфа о пользователе. ну и понятно что там есть login и ид пользователя (uid).
Еще одна табл frends состоит из uid (обоpначает польpователя из таблицы users), и fuid - это поле тоже ИД пользователя из табл users, но в таблице frends этот столбец идетифицирует друга "столбца uid". И назвал я его fuid.
Таблица имеет следующий вид:
uid fuid dateAdd
--- ---- -----
1 7
1 5
1 12
1 23
5 8
6 4
5 3
3 4
8 10
11 2
|
---
ДОПИСЫВАЮ: в этой таблице есть еще и третье поле "дата добавления", но это в данном случае не важно.
---
Что это означает. Это значит что у пользователя с ИД 1 есть друзья с ИД 7, 5, 12, 23.
Что нужно: Нужно для пользователя с ИД 1 узнать\выбрать логины его друзей.
В консоли по запросу
mysql> select login from users where uid=(select fuid from frends where uid=1);
ERROR 1242 (21000): Subquery returns more than 1 row
mysql>
|
это понятно, потому что запрос вернул не одно значение.
Для пользователя с одним другом все работает.
mysql> select login from users where uid=(select fuid from frends where uid=2);
+---------+
| login |
+---------+
| alex123 |
+---------+
1 row in set (0.00 sec)
mysql>
|
---
Я еще не учел то что при добавлении друга нужно записать также и другому пользователю этого друга. Подробнее: Например пользователь с ИД 8 добавил себе в друзья пользователя с ИД 100. В бд будет записано что у ИД 8 имеется друг с ИД 100. А пользователю с ИД 100 тоже нужно записать друга с ИД 8.
---
Или писать во второй столбец логин пользователя??? Все равно для составления ссылки (html код на php) нужен будет логин. Только возникнет проблема избыточного хранения инфы и размер бд будет больше чем он должен быть.
---
Может это все неправильно ? как сделать правильнее? Может есть (да конечно есть) примеры алгоритмов? Мне не готовый код нужен а обобщенные алгоритмы, НО где они? | |
|
|
|
|
|
|
|
для: root_xxx
(10.11.2014 в 04:23)
| | Вы не могли бы поточнее сформулировать главный вопрос?
для вас, и на данный момент
Потому что на этот поток сознания ответить можно разве что - таки да, join! | |
|
|
|
|
|
|
|
для: Trianon
(10.11.2014 в 11:48)
| | ??? Я все детально, НЕкратко :) описал, НО придется еще раз
Есть 1 табл. в ней есть ИД и логин пользователя.
Есть вторая таьбл в ней есть три поля ИД - указывает на ИД в первой таблице и есть поле ФИД - оно тоже указывает на поле ИД с первой тблицы. Третьбе поле второй табл ДАТА - это не столь важно.
Вторая таблица имеет слелдующее содержание
ИД ФИД дата еще_что_то
1 5 ...
1 2 ...
1 3 ...
6 4 ...
6 7 ...
6 3 ...
|
Это означает что у пользователя с ИД 1, есть друзья с ИД 5, 2, 3 (во второй табл это поле названо ФИД).
Нужно для пользователя с ИД 1 вывести всех его друзей (вывести логины из ПЕРВОЙ табл, основываясь на ФИД во второй таблице). | |
|
|
|
|
|
|
|
для: root_xxx
(10.11.2014 в 12:03)
| |
SELECT
u.login, u.uid, f.dateadd
FROM
friends f
JOIN users u ON f.fuid = u.uid
WHERE f.uid = 2
ORDER BY f.dateadd
|
например | |
|
|
|
|
|
|
|
для: Trianon
(10.11.2014 в 12:12)
| | ага, щас попробую...
---
вау!!! работает, но немного по другому. Щас пример покажу
mysql>
mysql> select uid,login from users;
+-----+---------+
| uid | login |
+-----+---------+
| 1 | root_x |
| 2 | xuser |
| 4 | alex123 |
| 5 | newuser |
+-----+---------+
4 rows in set (0.00 sec)
mysql> select * from frends;
+--------+--------+------------+
| p_fuid | s_fuid | adddate |
+--------+--------+------------+
| 1 | 2 | 2014-11-10 |
| 1 | 5 | 2014-11-10 |
| 2 | 4 | 2014-11-11 |
+--------+--------+------------+
3 rows in set (0.00 sec)
mysql>
|
Пришлось переименовать поля uid (из табл users) в p_fuid - primary frend
fuid в s_fuid - secjndary frend
Переименовал потому что была ошибка про то что и в табл users и в табл frends были одинаковые имена стлбцов.
НО весь этот "поток сознания" понятен только мне ;:))
РЕЗУЛЬТАТ такой:
mysql> select uid,login,adddate from users join frends on s_fuid=uid where p_fuid=1;
+-----+---------+------------+
| uid | login | adddate |
+-----+---------+------------+
| 2 | xuser | 2014-11-10 |
| 5 | newuser | 2014-11-10 |
+-----+---------+------------+
2 rows in set (0.00 sec)
mysql> select uid,login,adddate from users join frends on s_fuid=uid where p_fuid=2;
+-----+---------+------------+
| uid | login | adddate |
+-----+---------+------------+
| 4 | alex123 | 2014-11-11 |
+-----+---------+------------+
1 row in set (0.00 sec)
mysql>
|
Вот это и нужно было. НО я вчера и сгеодня ночью перед тем как задать вопрос искал в нете, смотрел в книгу (бумажную!) но так до меня и не дошло. А в тех примерах что я находил все было очень запутано (и даже на этом форуме нечто похожее есть) - но до меня только что дошло!
А щас все понял. И это так просто оказалось.
select uid,login,adddate from users join frends on s_fuid=uid where p_fuid=1;
FROM указывает откуда , а JOIN какбэ связывает таблицы и какбэ создает одну табличку.
И главное ON - сопоставляет поле из одной таблицы с полем во второй. Ну и условие... | |
|
|
|
|
|
|
|
для: root_xxx
(10.11.2014 в 12:14)
| | переименовывать поле совсем необязательно было.
В SQL можно (на лету) назначать алиасы(псевдонимы) как таблицам, так и полям.
Для столбцов имя поля можно уточнять именем/алиасом таблицы.
Алиасы имен таблиц ( u для users и f для friends) я показал выше.
Уточнения ( u.login , f.uid ) тоже показал.
Точно также можо было назначить алиас столбику. Например:
SELECT
u1.login orig_login, u2.login friend_login, addate
FROM
users u1
LEFT JOIN friends f ON f.p_uid = u.uid
LEFT JOIN users u2 ON u2.uid = f.s_uid
ORDER BY orig_login, friend_login, addate
|
| |
|
|
|
|
|
|
|
для: Trianon
(12.11.2014 в 00:43)
| | Обращение имя таблицы,.поле_таблицы - в примерах выше не работает.
Щас проверю ваш последний пример...
хм-м... что-то :)) выводит
mysql> SELECT u1.login orig_login, u2.login friend_login, adddate
FROM users u1
LEFT JOIN frends f ON f.p_fuid = u1.uid
LEFT JOIN users u2
ON u2.uid = f.s_fuid
ORDER BY orig_login, friend_login, adddate ;
+------------+--------------+------------+
| orig_login | friend_login | adddate |
+------------+--------------+------------+
| alex123 | NULL | NULL |
| newuser | alex123 | 2044-10-09 |
| newuser | root_x | 2023-08-08 |
| newuser | xuser | 2014-11-26 |
| root_x | alex123 | 2015-10-01 |
| root_x | newuser | 2014-11-10 |
| root_x | xuser | 2014-11-10 |
| xuser | alex123 | 2014-11-11 |
| xuser | newuser | 2023-10-01 |
| xuser | root_x | 2014-10-01 |
+------------+--------------+------------+
10 rows in set (0.01 sec)
mysql>
|
Та да. Все правильно выводит, НО именно такого вывода не нужно. В алгоритме (в коде) нужно для одного пользователя вывести (или узнать ИД друзей для последующей обработки) всех его друзей. | |
|
|
|
|
|
|
|
для: root_xxx
(12.11.2014 в 12:42)
| | Алгоритму - может быть и да.
А Вам?
Впечатление такое, что код из моего ответа Вы увидели, а человеческий текст решили проигнорировать.
>Обращение имя таблицы,.поле_таблицы - в примерах выше не работает.
Запятая откуда?
Точка, а не запятая. | |
|
|
|
|
|
|
|
для: Trianon
(12.11.2014 в 13:46)
| | да там же и точка есть. То просто опечатка. | |
|
|
|
|
|
|
|
для: root_xxx
(12.11.2014 в 14:32)
| | так и что не работает?
как раз в отклике mysql видно, что работает | |
|
|
|
|
|
|
|
для: Trianon
(12.11.2014 в 14:50)
| | та сейчас все работает. А в ваших первых примерах не работало потому что выводилась ошмбка об одинаковыхз именах столбцов. Точно уже не помню.
---
А что если писать FROM users AS u1 ? Это же кажись одно и то же, если пишется FROM users u1 - это неявная форма AS ? | |
|
|
|
|
|
|
|
для: root_xxx
(12.11.2014 в 14:55)
| | AS можно опустить, это одно и тоже. | |
|
|
|
|
|
|
|
для: lgar
(04.01.2015 в 17:59)
| | AS желательно опускать - код от этого становится более переносимым.
Насколько мне не изменяет память, в оракле, например, AS писать просто нельзя. | |
|
|
|
|
|
|
|
для: Trianon
(04.01.2015 в 21:39)
| | >Насколько мне не изменяет память, в оракле, например, AS писать просто нельзя.
Не знаю, как сейчас, но два года назад было можно. В оракле нельзя писать || и & вместо OR и AND, это я точно помню, сама попадалась. | |
|
|
|
|
|
|
|
для: Лена
(05.01.2015 в 15:52)
| | В оракле нельзя писать || и & вместо OR и AND
А что есть непреодолимое желание??? :D
Мне например и в голову не приходило писать такое в запросах (неважно к какой СУРБД) | |
|
|
|
|
|
|
|
для: Valick
(05.01.2015 в 16:06)
| | >А что есть непреодолимое желание??? :D
>Мне например и в голову не приходило писать такое в запросах (неважно к какой СУРБД)
Экономия времени :)
Я писала по аналогии с php. | |
|
|
|
|
64.8 Кб |
|
|
для: Лена
(05.01.2015 в 15:52)
| | Я ж это тоже не сам придумал...
В MySQL AS может использоваться как указатель псевдонима поля (в списке SELECT)
а может как указатель псевдонима табличного выражения
FROM products AS p JOIN prices AS r ON r.prod = p.id
|
Второй вариант применения AS в oracle не проходит.
См приложенную картинку, место я пометил красным.
В первом варианте AS можно опускать.
Вот с тех пор как я это фе увидел, не пишу AS нигде.
Хотя тоже поначалу старался.
Источник | |
|
|
|
|
|
|
|
для: Trianon
(05.01.2015 в 16:25)
| | Я вооюще не использую у себя AS. Потому что надобнности нет. Я изначально хорошо называю таблицы и поля. Обхожусь без AS`ов. | |
|
|
|
|
|
|
|
для: root_xxx
(05.01.2015 в 22:41)
| | >Потому что надобнности нет.
Просто вы еще не писали запросы при которых без алиасов просто нельзя. | |
|
|
|
|
|
|
|
для: Valick
(05.01.2015 в 23:15)
| | но ведь в программировании как-бэ есть неписанное правило: нужно придерживаться простоты и жизнь будет легче. | |
|
|
|
|
|
|
|
для: root_xxx
(10.01.2015 в 18:38)
| | Вот как? Но тогда почему вы используете SQL, а не машину Тьюринга? :) | |
|
|
|
|
|
|
|
для: Trianon
(12.11.2014 в 13:46)
| | >Алгоритму - может быть и да.
>А Вам?
Ну разве что для просмотра и проверки правильности выборки. | |
|
|
|