powered by simpleCommunicator - 2.0.19     © 2024 Programmizd 02
Map
Форумы / MySQL [игнор отключен] [закрыт для гостей] / В Left Join подставлять определённую запись для отсутствующих
25 сообщений из 25, страница 1 из 1
В Left Join подставлять определённую запись для отсутствующих
    #40132410
Sergey Kasatkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сразу на примере, чтобы было проще.

Пусть есть две таблицы:
U - пользователи форума (id, name)
P - посты на форуме (id, txt, u_id --> U.id)

Требуется: вывести список текстов из постов таблицы P и соответствующие им ники пользователей U.name.
В нормальном простейшем случае имеем:

Код: sql
1.
2.
3.
select U.name, P.txt
from P
 inner join U on P.u_id = U.id



Но для некоторых постов (записей P ) отсутствуют соответствующие им записи пользователей таблицы U (да, мы про реальную жизнь).
При этом в таблице U точно есть отдельная запись с U.id = -1 "Anonymous" (default-пользователь)

Задача :
Вывести U.name, P.txt так, чтобы
- если соответствие есть - выводилось реальное имя пользователя
- если соответствующего пользователя (записи в U) нет - выводилось U.name из строки с U.id = -1

Понятно, что решить можно на разных уровнях, и в прикладном коде можно.
Но было бы интересно обсудить варианты решения в SQL.

Поделитесь хорошими идеями, плиз! в синтаксисе пригодном для MySQL
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132411
Sergey Kasatkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я придумал только такой вариант:

Код: sql
1.
2.
3.
4.
select u2.name, P.txt
from P
left join U u1 on P.u_id = u1.id
inner join U u2 on IFNULL(u1.id,-1) = u2.id



Не проверял, но на вид должно работать.

Есть ли способы производительнее?
Быть может с переменными как-то? с предварительным получением записи -1 в переменные и потом подстановка из них при надобности?
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132437
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey Kasatkin,

условие в соединении таблиц не сработает
это условие сработает в выводе

Код: sql
1.
2.
3.
4.
select IFNULL(u1.nm,u2.nm), p.txt
from P p
left join U  u1 on p.u_id = u1.id 
inner join U u2 on u2.id=-1
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132454
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторНе проверял, но на вид должно работать.сейчас есть отличные онлайн ресурсы, проверяй не хочу

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=45b427b6281aae7ee4c4ed35a3acf4c7
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132458
Sergey Kasatkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alex_Ustinov ,

За ссылку с подготовленным кейсом - большое спасибо!
Кстати, там же проверил - мой вариант тоже работает корректно.

Причем формально мой вариант "правильнее" вот для какого случая: если нужная нам запись в U есть, но name в ней почему-то NULL (в жизни, понятно, выбираются какие-то еще поля), то, согласно постановке, будет некорректно взять значение для name из записи с U.id = -1
Это если придираться.

Однако меня, скорее, волнует вопрос производительности.
Хочется найти максимально быстрый вариант SQL для указанной задачи.
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132470
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Sergey Kasatkin, а чего не просто

Код: sql
1.
2.
3.
select IFNULL(u.nm,"Anonymous"), p.txt
from p
left join u on p.u_id = u.id 


Полагаю, это и будет максимально быстро
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132472
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чё так сложно-то? две копии таблицы, фэйк-запись... понакрутили...

Код: sql
1.
2.
3.
4.
SELECT COALESCE(user.name, 'Anonymous') name,
       post.txt
FROM post
LEFT JOIN user USING (user_id)


https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=a488517f51ed0cbe7fea028b0108aff3
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132498
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
читаем тз -
вывести вместо NULL Name c id=-1
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132504
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_Ustinov
читаем тз -
вывести вместо NULL Name c id=-1

С учётом того, что
Sergey Kasatkin
в таблице U точно есть отдельная запись с U.id = -1 "Anonymous" (default-пользователь)

это означает - вывести литерал 'Anonymous' .
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132507
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina,

вывести с id=-1
"Литерал" для БД - сегодня Анонимус, завтра Шрайбикус

Sergey KasatkinКстати, там же проверил - мой вариант тоже работает корректно.
да, так точно
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132511
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey Kasatkin,

В поле P.u_id могут быть NULL-ы (не из-за джойна, а в таблице) ? И как их нужно обрабатывать?
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132520
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_Ustinov
"Литерал" для БД - сегодня Анонимус, завтра Шрайбикус

Можно полюбопытствовать, почему во фразе
Sergey Kasatkin
При этом в таблице U точно есть отдельная запись с U.id = -1 "Anonymous" (default-пользователь)

Вы информацию о гарантированном существовании записи ("точно есть отдельная запись") связываете с id , но отказываете в точно такой же связи с name ?
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132525
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina,

вы это "теплое с мягким не путайте" ...
к чему так много умных слов.
я четко описал почему.
Если потребуется вывести "Пупкин" - полезем переделывать запрос?
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132527
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не я кивал на ТЗ. Уж если апеллировать к нему, то ко всему сразу, а не только к той части, которая понравилась.
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132552
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina
Не я кивал на ТЗ. Уж если апеллировать к нему, то ко всему сразу, а не только к той части, которая понравилась.
болельщикам Реал Мадрида я обычно говорю - "едрить-мадрить"
читаем тз

авторЗадача:
Вывести U.name , P.txt так, чтобы
- если соответствие есть - выводилось реальное имя пользователя
- если соответствующего пользователя (записи в U) нет - выводилось U.name из строки с U.id = -1
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132614
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И опять - одну часть ТЗ, удобную, гордо цитируем.
А другую часть:
Sergey Kasatkin
При этом в таблице U точно есть отдельная запись с U.id = -1 "Anonymous" (default-пользователь)

стыдливо так не замечаем? потому как она чётко определяет то самое значение "U.name из строки с U.id = -1"... а это неудобно.
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132638
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina
стыдливо так не замечаем?я ни ОДНОЙ своей ошибки-неточности не стыжусь.
Я это это не то что заметил, а 55 раз перечитал.
сверху - ПОДВОДКА.
ТЗ - подчеркнуто . ПОДЧЕРКНУТО.

Почему так зацепило такое элегантное решение у ТС?
При использовании табличной подстановки с Id=-1 в 50-ти запросах для изменения "Анонимуса" на "Шрайбикуса"
достаточно Апдейта 1-й записи, а не исправления 50-ти запросов.

Ваше решение правильно по "подводке", но не по ТЗ.
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132659
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_Ustinov
Почему так зацепило такое элегантное решение у ТС?

Использование лишней с точки зрения логики копии таблицы - как минимум.

Непрозрачность логики (дай голый текст запроса кому-нить и попроси сказать, что он делает...).

Не говорю уж о том, что существование записи с внешним дефолтным значением (не путать с атрибутом DEFAULT) и отрицательным уникальным индексом - далеко за пределами best practice.

Ладно. Нафиг. Будем считать что Вы правы.
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132693
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я уже допустил, что отчасти вы правы.
Хотя "best practice"...

а что такое "best practice"?
у нас в эту зиму - валенки, хотя юг... а год назад в шортах в декабре в магазин ходил...)

......
5 минут думал как объяснить... нафиг
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132748
Sergey Kasatkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina
И опять - одну часть ТЗ, удобную, гордо цитируем.
А другую часть:
Sergey Kasatkin
При этом в таблице U точно есть отдельная запись с U.id = -1 "Anonymous" (default-пользователь)

стыдливо так не замечаем? потому как она чётко определяет то самое значение "U.name из строки с U.id = -1"... а это неудобно.

Если уж строго читать ТЗ и к нему аппелировать, но в приведённой вами цитате никак не сказано, что значение поля U.name точно равно "Anonymous" для записи с U.id = -1. Это вы все же додумываете то, чего нет, согласитесь :)

Просто запись с U.id = -1 таблицы U условно назовем "Anonymous". ничего иного в ТЗ не написано ;)
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132797
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey Kasatkin
Просто запись с U.id = -1 таблицы U условно назовем "Anonymous".

Таблица пользователей U хранит экземпляры сущности Пользователь.

Однако Anonymous экземпляром этой сущности не является. Ибо не существует однозначно идентифицированного экземпляра объекта, который соответствует этой записи. Данное значение является шаблоном-заполнителем, применяемым в случае невозможности однозначно идентифицировать связанный экземпляр сущности. То есть это шаблон, фактически применяемый при обработке особой ситуации на уровне приложения. Следовательно, он должен идентифицироваться как элемент настройки приложения, экземпляр сущности "Настроечная Переменная".

А потому запись с Anonymous не должна присутствовать в таблице пользователей. Это значение может быть опцией настройки, хранимой обычным образом (в том числе и в специальной служебной таблице) либо константой, включаемой в код программы хардкодом.
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40132999
Sergey Kasatkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina
Данное значение является шаблоном-заполнителем, применяемым в случае невозможности однозначно идентифицировать связанный экземпляр сущности. То есть это шаблон, фактически применяемый при обработке особой ситуации на уровне приложения.


Не совсем понятно почему именно "на уровне приложения" на ваш взгляд. Чем код приложения, выполяемыей на SQL-сервере, не годится для реализации данной бизнес-логики? (SQL-запросы - это часть кода приложения, согласитесь.)
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40133041
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Sergey Kasatkin

Не совсем понятно почему именно "на уровне приложения"

Да потому что
Akina

Таблица пользователей U хранит экземпляры сущности Пользователь.
Однако Anonymous экземпляром этой сущности не является.

Он станет таковым, если в таблице постов заменить все неизвестные u_id на -1 (будет означать Неизвестный пользователь)
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40133070
Sergey Kasatkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
paver
Sergey Kasatkin

Не совсем понятно почему именно "на уровне приложения"

Да потому что
Akina

Таблица пользователей U хранит экземпляры сущности Пользователь.
Однако Anonymous экземпляром этой сущности не является.


Вопрос мой был "почему на уровне приложения" непременно следует решать этот вопрос, а не на уровне SQL-сервера.
Не могу ваше объяснение понять.
Вопрос "философский", конечно, и всё же. Есть некая логика алгоритма, которую надо организовать. Почему на языке SQL её, по вашему мнению, реализовать неправильно, а на другом языке - правильно?

paver
Он станет таковым, если в таблице постов заменить все неизвестные u_id на -1 (будет означать Неизвестный пользователь)

А вот это здравая мысль. В самом деле: какой смысл хранить id пользователя, которого по каким-то причинам уже нет? можно и "забыть" его "реальный" id, т.к. никакой ценности он уже не несет, информации о пользователе этом нет.
Спасибо!
...
Рейтинг: 0 / 0
В Left Join подставлять определённую запись для отсутствующих
    #40133125
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Sergey Kasatkin

Вопрос мой был "почему на уровне приложения" непременно следует решать этот вопрос, а не на уровне SQL-сервера.

Потому что SQL - язык манипулирования реляционными БД. Диалог о суслике модели сущность-связь:

- Видишь связь между экземплярами (5, 'Salut', 55) и (-1, 'Anonymous') сущностей Пост и Юзер соответственно?
- Нет
- А она есть!
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / В Left Join подставлять определённую запись для отсутствующих
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (0):
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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