Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 10.09.2019 22:08:37

Subquery в join

Помогите выразить на Query Builder без RAW, но через joinSub или подобный механизм вот такой непростой запрос:

SELECT
  SUM(w.weight) AS weight
FROM container AS c
JOIN weight AS w ON w.id = ( -- First weight
	SELECT MIN(id) FROM weight WHERE container_id = c.id
)
LEFT JOIN container_run AS cr ON cr.id = ( -- First link to process if any
	SELECT MIN(id) FROM container_run WHERE container_id = c.id
)
WHERE 
  cr.type = 1 OR cr.type IS NULL

Изменено doublevas (10.09.2019 22:28:20)

Не в сети

#2 10.09.2019 22:13:51

Re: Subquery в join

Запрос на сыром SQL работает как надо. Не хочется в Laravel писать всё через DB::RAW() это как-то неэстетично.

Колдунство с
JOIN xxx ON id = SELECT MIN(id) FROM xxx WHERE fk_id = yyy.id
понадобилось так как надо прицепить первую из нескольких подходящих записей.

Тому гуру Eloquent кто осилит перевод, от меня будет огромный респект!

Не в сети

#3 12.09.2019 10:30:30

Re: Subquery в join

Сложные у тебя запросы. Честно, с джойнами почти не работаю. Их заменяют такие функции как has, with, whereHas , подробнее например -
http://www.itmathrepetitor.ru/laravel-5 … -wherehas/
Правда результат и его обработка будет чуток отличной, зато код понятнее и меньше. А иногда и быстрее.
В кратце - что бы написать конструкцию типа Сontainer::with('weight', 'container_run')->where('id',1)->get(); Нужно что бы в модели Сontainer, которая работает по таблице container, была прописана связь (один к одному, один ко многим) к таблицам weight и container_run, которые так же имеют свои модели. Подробнее - https://laravel.ru/docs/v5/eloquent#%D0 … 0%B8%D1%8F
А вот джойнить чёт у меня не получается big_smile

Изменено Alexandr5 (12.09.2019 10:52:55)

Не в сети

#4 12.09.2019 12:13:49

Re: Subquery в join

То, что данный отчёт получается сложным не означает, что нужно рефакторить всё к чёртовой бабушке чтобы оно гладко описывалось через has smile

Здесь загвоздка скорее в ограниченных возможностях Eloquent, а не в плохой модели. Eloquent это надстройка над или пре-компилятор SQL. Он по определению не может дать больше, чем даёт SQL. Хотя некоторые типовые действия выглядят в нём удобно.

Всё же я надеюсь, что удастся найти хороший перевод.

Не в сети

#5 12.09.2019 12:31:52

Re: Subquery в join

Это понятно и я не говорю всё менять. Так, на будущее, если не знал.:) Я тут сильно экспериментировал с запросами и открыл для себя, что иногда два запроса лучше одного, а Eloquent сам может разделить одну конструкцию на несколько запросов.
Кароооче. Твой запрос перенести мне слабо, но можно попробовать написать несколько запросов.

Не в сети

#6 12.09.2019 13:19:46

Re: Subquery в join

Я согласен с тем что бывает удобнее несколько запросов чем один. Но данный пример я не знаю как переписать ни в один, ни в несколько запросов чтобы не было очевидного бестолкового оверхеда. PHP не должен брать на себя функцию сервера БД.

Продублировал вопрос на laracast в предельно упрощённом виде, может там подскажут.

Изменено doublevas (12.09.2019 13:21:38)

Не в сети

#7 17.10.2019 03:10:21

Re: Subquery в join

Я согласен с тем что бывает удобнее несколько запросов чем один. Но данный пример я не знаю как переписать ни в один, ни в несколько запросов чтобы не было очевидного бестолкового оверхеда.

ПРивет, я понимаю, что ничем тебе не помогу в моем сообщении, но могу узнать.. ?
Зачем использовать ларкин Eloquent для сложных запросов.. да и вообще для запросов.. почему бы все запросы не отправлять в RAW формате, ведь на обработку RAW запросов требуется минимальное кол-во времени (Eloquent в таком случае не нужно строить RAW строку для твоих запросов в стелочном синтаксисе.. он же все в конце концов приводит к RAW и отправляет такой запрос в БД..)

Еще одно преимущество в использовании RAW запросов - изучени и практика работы с sql синтаксисом.. ведь он всегда один и тот же.. а вот php оберток написано для него много и все они в итоге преобразют твой синтаксис в raw запрос..

Не в сети

#8 08.11.2019 23:43:48

Re: Subquery в join

C Eloquent и вряд ли получится в слепую написать правильно запрос. Но на sql языке другое дело.
Ваш запрос с джойнами с вложенных под запросов это очень глупое решение при больших таблицах, и если его переписать то он не такой и страшный получается вот вам 2 варианту, можете использовать любой на выбор:

SELECT
    DISTINCT SUM(min(w.weight)) OVER ()
FROM container AS c
    LEFT JOIN weight AS w ON w.container_id = c.id
    LEFT JOIN container_run AS cr ON cr.container_id = c.id
WHERE cr.type = 1 OR cr.type IS NULL
GROUP BY c.id;
SELECT sum(test.weight)
FROM (
SELECT
    min(w.weight) AS weight
FROM container AS c
    LEFT JOIN weight AS w ON w.container_id = c.id
    LEFT JOIN container_run AS cr ON cr.container_id = c.id
WHERE cr.type = 1 OR cr.type IS NULL
GROUP BY c.id
    ) AS test

Не в сети

Подвал раздела