LINUX.ORG.RU

Postgesql 9.6 - вернуть master и detail одним запросом

 ,


0

1

Выйдя из криокамеры, пытаюсь понять, насколько далеко зашёл прогресс. Мне нужно создать страничку, на ней есть строки, и в каждой строке - какие-то поля и таблица детальных данных. Я понял, что это можно сделать, если свернуть детальные данные в json, или сделать отдельно запрос на строки и отдельно на детали, далее идти по ним параллельно, или денормализовать данные и идти по одному запросу, в котором данные «мастера» будут повторяться для каждой детальной строки. Всё это не особо классно. Я правильно понимаю, что нельзя в поле запроса вложить некую «таблицу»? Мне просто грезилось, что такое уже сделано, но почему-то найти не получается ни типов данных в документации, ни ответов на подобные вопросы на SO.

Пишу программку на go, пытаюсь использовать связку sqlx + pgx. sqlx использовал в прошлом воплощении данной поделки, а pgx мне разрекламировали тут

★★★★★

В чем проблема, вернуть два запроса:

В одном поля из Master, а в другом поля из Detail и ID мастера.

wandrien ★★
()
Ответ на: комментарий от wandrien

Да, так я раньше и делал. Тут есть ряд вопросов, например, если запросы не в одной транзакции, то данные могут поменяться в зазоре между этими запросами, и эту ситуацию нужно обрабатывать.

den73 ★★★★★
() автор топика

Ты хочешь https://devdocs.io/postgresql~9.6/functions-aggregate#json_agg ?

если свернуть детальные данные в json

Ну да. У тебя есть более интересные варианты?

array_agg технически тоже возможен, но тебе скорее всего придётся обрабатывать его на стороне клиента, поэтому обычно пользуют json_agg/jsonb_agg.

x3al ★★★★★
()
Последнее исправление: x3al (всего исправлений: 1)
Ответ на: комментарий от Legioner

Тем, что данные из главной таблицы будут дублироваться для каждой записи из второстепенной. Да, это так работает, просто хотелось в XXI веке чего-то более красивого.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Ну можешь с JSON-ми или массивами извратиться… Но так никто не делает. В 21-м веке делают ровно так же, как и в 20-м: join-ом. А результаты ORM обычно разбирает и строит уже нужную объектную структуру. Ну или ручками, не так уж это и сложно.

Legioner ★★★★★
()
Ответ на: комментарий от x3al

Я хочу убедиться, что ничего более интересного нет. Я предполагал, что уже запилили что-то такого типа:

select master.*, (select * from detail where detail.masterid = master.id) as det where ... 

И далее на клиенте вложенный цикл:

цикл_для m из результат_выборки делай
  пиши m.id, m.name
  цикл_для d из m.det делай
    пиши d.name кн кн

И мне казалось, что такое уже сделали. Видимо, это были только мои мечты, а на самом деле такого нет. Да, в случае json примерно так и получится. Но как-то это противоестественно, брать прекрасную реляционную парадигму и к ней в виде сарая пристраивать json.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от Legioner

Века идут, а каменный топор остаётся. Ладно, всё понял, всем спасибо. Попробую через json ради расширения кругозора.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

select master.*, (select * from detail where detail.masterid = master.id) as det where …

Это и есть array_agg. Тебе же в любом случае нужно делать GROUP BY master.id.

x3al ★★★★★
()
Ответ на: комментарий от x3al

Не, это не SQL, а мифический SQL будущего, который возвращает не плоский набор данных, а нечто, похожее по структуре на такой «json»

[{id: 1, name: master1, det:
  [{id: 1, name: detail1, masterid: 1},
   {id: 2, name: detail2, masterid: 1}]},
 {id: 2, name: master2, det:
  [{id: 1, name: detail3, masterid: 2},
   {id: 2, name: detail4, masterid: 2}]}]

Ну ок, можно попробовать и через массивы.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

Как-то так в json:

select tsense.*, 
  (select jsonb_agg(row_to_json(detail)) 
   from 
     (select tlws.* from tlws 
      where senseid=tsense.id 
      order by word) as detail) as tlws
from tsense; 

Возвращает строки tsense, и для каждой - связанные с ней строки из tlws.

den73 ★★★★★
() автор топика

Каждый раз когда на форуме поднимается этот вопрос, все скулята включают дурачка и недоумевают, зачем нужно недублировать данные мастера. Это такой стокгольмский синдром мирового масштаба, т.к. не только на лоре наблюдается. Прогресс замечен в том, что если раньше говорили «ну да, пока нет», то сейчас агрессивно рычат и показательно не понимают вопроса. Расслабься и получай двумя запросами, если деталь сильно больше, либо джойном, если ее там х2-х3.

anonymous
()
Ответ на: комментарий от anonymous

Ну я пока json-ом попробую. Это, конечно, абсурд, но json сейчас в моде, можно будет гордо на собеседовании сказать, что я это умею. Запрос написал, осталось только на клиенте json распарсить - видимо, это будет одна-две магических строчки.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)

вернуть master и…

Ёмае, sjw на тебя нет)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.