powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Простой-сложный select
24 сообщений из 24, страница 1 из 1
Простой-сложный select
    #39256630
aliskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
таблица: m_frend дружит со sl_frend (в примере 883 дружит с 876), НО есть записи в которых другие uid`ы дружат с m_frend (то есть в таком случае m_frend будет sl_frend`ом). Пример 856 дружит с 883.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
    mysql> select * from frends ;
    +---------+----------+-------+
    | m_frend | sl_frend | fr_st |
    +---------+----------+-------+
    |     883 |      876 |     1 |
    |     880 |      875 |     1 |
    |     881 |      877 |     1 |
    |     856 |      883 |     1 |
    |     859 |      883 |     1 |
    |     860 |      883 |     1 |
    |     883 |      879 |     1 |
    |     883 |      880 |     1 |
    |     883 |      881 |     2 |
    +---------+----------+-------+
    9 rows in set (0.01 sec)



Нужно в одном запросе, ОДНИМ СТОЛБИКОМ, вытянуть всех друзей 883 (тех с кем дружит 883), и ТЕХ КТО ДРУЖИТ С 883.

Такой вот калмбурчик вышел, надеюсь проблему описал понятно. И реально ли это сделать (получить результат в одном столбце)?

- - -
Знаю что можно сначала получить

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
   mysql> select * from frends where m_frend=883 or sl_frend=883;
    +---------+----------+-------+
    | m_frend | sl_frend | fr_st |
    +---------+----------+-------+
    |     883 |      876 |     1 |
    |     856 |      883 |     1 |
    |     859 |      883 |     1 |
    |     860 |      883 |     1 |
    |     883 |      879 |     1 |
    |     883 |      880 |     1 |
    |     883 |      881 |     2 |
    +---------+----------+-------+
    7 rows in set (0.00 sec)


а потом в коде отбросить 883. но как результат запроса получить одним столбцом?
...
Рейтинг: 0 / 0
Простой-сложный select
    #39256632
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aliskin,

union спасёт отца русской демократии
...
Рейтинг: 0 / 0
Простой-сложный select
    #39256642
aliskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как все просто.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
mysql> SELECT sl_frend AS frend_id FROM frends WHERE m_frend = 883     UNION SELECT m_frend AS frend_id FROM frends WHERE sl_frend = 883;
+----------+
| frend_id |
+----------+
|      876 |
|      879 |
|      880 |
|      881 |
|      856 |
|      859 |
|      860 |
+----------+
7 rows in set (0.00 sec)
...
Рейтинг: 0 / 0
Простой-сложный select
    #39256643
aliskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я так понял что столбЦЫ переименовываются по AS, а дальше понятно.
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257605
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А так?
SELECT (m_frend + sl_frend - 883) AS frend_id FROM frends WHERE m_frend = 883 OR sl_frend = 883;
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257622
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT DISTINCT
    CASE 
        WHEN m_frend=883 THEN sl_frend
        WHEN sl_frend=883 THEN m_frend
    END friend
FROM friends 
HAVING friend IS NOT NULL;
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257642
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Тоже красиво. Но как понимаю, без where придется шерстить всю таблицу?
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257663
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А её так и так шерстить всю, если нет нужных индексов - но в моём варианте один раз, а не два. А если они есть, то имхо самый быстрый по выполнению вариант - это UNION ( 19297411 ).
Да и вариант
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT DISTINCT
    CASE m_frend
        WHEN 883 THEN sl_frend
        ELSE m_frend
    END friend
FROM frends 
WHERE m_frend=883 OR sl_frend=883;


тоже не самый неудачный будет.
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257680
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну у меня вроде то же самое написано (дистинкт только добавить).
А почему юнион быстрее? Все же 2 селекта?
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257688
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
paverпочему юнион быстрее?Если есть ДВА индекса - по m_frend и по sl_frend,- и у них высокая селективность, то в случае UNION для каждого подзапроса будет использоваться наиболее подходящий индекс (а если они покрывающие - вообще сказка). А для остальных - максимум один из них, а если они не покрывающие, что скорее всего во всех остальных случаях будет fullscan.
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257691
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
paverу меня вроде то же самое написано (дистинкт только добавить) ихде?
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257699
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот жеж 19303982
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257722
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ааа... это я пропустил - код не в теге не воспринимается как код.
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257769
aliskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
мне написали на одном ихз форумов
автор
Тут с одной стороны все понятно с UNION. Но посмотрите немного глубже. Структура таблиц не соответсвует принципам реляционных баз данных. Чем у Вас левый товарищ может отличаеться от правого? Они же совершенно равноправны. Тут лучше использовать такую структуру Люди (ИД) Отношение товарищества (ИД) Товарищи (ИД_Отношения_товарищества, ИД_Человека)

Конечно, тут придется использовать цже не UNION, а JOIN.


а вы как считаете?

Мой ответ:
автор
НЕЕТ! Это таблица дружественных отношений. ВСЯ ДРУЖБА уже абсоолютно верно обраабатывается и вывод кнопок в профиле тоже уже железно написан. Все так как должно быть.. Отличия в том что левый товарищ первым подает заявку в друзья второму (правому товарищу.)
---
Откуда люди столько знают о мСэКюэЛе?
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257771
aliskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Откуда люди столько знают о мСэКюэЛе?
---
это моя мысля..
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257784
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aliskin а вы как считаете?
А мы не в курсе.
Если то, что "А друг Б", означает автоматически, что "Б друг А", то что-то осмысленное (но именно что-то) в возмущениях имеется.
А если нет - то это бред голимый.
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257791
aliskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akinaaliskin а вы как считаете?
А мы не в курсе.
Если то, что "А друг Б", означает автоматически, что "Б друг А", то что-то осмысленное (но именно что-то) в возмущениях имеется.
А если нет - то это бред голимый.
да А = Б, но

повторяюсь:
авторОтличия в том что левый товарищ первым подает заявку в друзья второму (правому товарищу.)
---
Кроме этого у мення есть таблица из ДВУХ полей. в ОБЕИХ полях ИД пользователей, но в этой тбл левый ИД означает что он заблокировал правый ИД.

Не хотел и дружбу и блокировку писать в одну тбл, поэтому и разделил на две.
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257792
aliskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да А = Б и Б = А, но ...
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257797
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторОтличия в том что левый товарищ первым подает заявку в друзья второму (правому товарищу.)А вот теперь смотри. У тебя начальное состояние - "А и Б не друзья". Конечное состояние "А и Б друзья". А ОДИНАКОВОМУ начальному и конечному состояниям могут соответствовать РАЗНЫЕ данные. Вот именно это и неправильно. Недетерминированность.

Поэтому правильной структурой в случае, если дружба симметрична, а порядок её установления незначим, с точки зрения нормализации будет (ИД юзера - ИД дружеских отношений). С ограничением COUNT(ИД дружеских отношений) = 2.
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257819
aliskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что значит "У тебя начальное состояние - "А и Б не друзья". Конечное состояние "А и Б друзья"."?

Дружба обрвбатыввается так(без кода но словами поясню):

Если записей в тбл блокировки нет, то идет обработка дружбы. Если есть записи в тбл блокировки (блэклист) то предпринимаются неките действия (например показ вообщ: полльзов заблокирован ВАМИ или Вы заблокированы пользователем.), Обработка дружбы не просходит. Какой смысл узнавать статус дружбы если ее нет?

Обработка дружбы: Если ТОТ пользователь (тут важно не путать пользователей: Поэтому ТОТ пользов - это будет пользователь профиль которого СМОТРИМ. А тот КТО смотрит - будем называть "Я").

Так воот: Если ТОТ пользователь незаблокирован и МЕНЯ он не заблокировап, И УЖЕ подал заявку в друзя, то


при подтверждении МОЕЙ дружбы с ТЕМ пользователем или при подаче МНОЙ заявки в друзья - статус дружбы установить 1 (то есть друзья).
---
Если ТОТ пользов не друг и не заблокирован - то добавить запись в тбл и поставить статус дружбы 2 (Я подал заявку и ожидаю дружбы).
---
Нуезнаю поняли ли вы мое написание, НО Смысл в тот, в тбл дружбы НИКОГДА не будет
Код: sql
1.
2.
3.
ид1    ид2 статусдр
833   755     х
755   833     х



ну и + к этому проверки чтобы уже заблокированные не смогли дружить без разблокировки. ПОЧЕМУ так: Потому что например вы сегодняч созранили страницу профиля пользователя у себя на копме. там есть книппки "добавить в друзья". завтра этот пользоватлеь вас аблокирует но ы вдруг захотите попробовать подаь ему заявку в друзья с сохраненной страницы. вот такиее ввсякме проверки у меня уже реилизованы.

Потому и оговорю что дружба уже написана абсолютно железно.
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257823
aliskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Akina]автор...Поэтому правильной структурой в случае, если дружба симметрична, а порядок её установления незначим, с точки зрения нормализации будет (ИД юзера - ИД дружеских отношений). С ограничением COUNT(ИД дружеских отношений) = 2.
Порядок установки важен.

Ну и как я смогу знать с кем дружит этот ИД, если вы написали что нужно ИД юзера и ИД дружОтношений? Все равно нужно связать ДВА ид пользователЕЙ (+ статус дружбы который их связывает).

Я выше уже хоть как-то написал о том что и как у меня.
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257827
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aliskinЧто значит "У тебя начальное состояние - "А и Б не друзья". Конечное состояние "А и Б друзья"."?Я выбираю два момента времени.
Первый - А и Б ещё не друзья, никаких заявок на дружбу меж собой не подавали. Соответственно в этот момент времени в твоей таблице НЕТ записи с их идентификаторами.
Второй - А и Б уже друзья, заявка подана, и она принята. С точки зрения детерминированности состояние БД должно быть однозначным. Но у тебя имеется два равновероятных состояния базы данных. Это и есть неправильность. Соответствие между состоянием системы и состоянием базы данных, хранящей сведения об этом состоянии, должно быть однозначным в обоих направлениях.

Однако твои последние пояснения говорят о том, что информация, кто кому подал заявку, на самом деле является значимым атрибутом дружбы. То есть второй момент времени может иметь два разных состояния: "А и Б друзья, причём заявку подал А" и "А и Б друзья, причём заявку подал Б". Каждому этому состоянию соответствует строго одно состояние базы данных. С точки зрения нормализации всё в порядке, и твоя структура - правильная. А то, что ты принял решение хранить сведения о том, кто подал заявку, именно таким способом - ну это дело твоё, имеешь право. Не очень удобно, зато лаконично и легко понимаемо.
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257833
aliskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
:) ага, а также огромный плюсище в легкости обработки статусов дружбы и вывод нужных кнопок в профиле.
...
Рейтинг: 0 / 0
Простой-сложный select
    #39257844
aliskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaЭто и есть неправильность. Соответствие между состоянием системы и состоянием базы данных, хранящей сведения об этом состоянии, должно быть однозначным в обоих направлениях.
Ну ведь у меня даже поля нажываються m(ain)_frend и sl(ave)_frend не просто так. :)
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Простой-сложный select
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]