Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Помогите выразить на 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)
Не в сети
Запрос на сыром SQL работает как надо. Не хочется в Laravel писать всё через DB::RAW() это как-то неэстетично.
Колдунство с
JOIN xxx ON id = SELECT MIN(id) FROM xxx WHERE fk_id = yyy.id
понадобилось так как надо прицепить первую из нескольких подходящих записей.
Тому гуру Eloquent кто осилит перевод, от меня будет огромный респект!
Не в сети
Сложные у тебя запросы. Честно, с джойнами почти не работаю. Их заменяют такие функции как 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
А вот джойнить чёт у меня не получается
Изменено Alexandr5 (12.09.2019 10:52:55)
Не в сети
То, что данный отчёт получается сложным не означает, что нужно рефакторить всё к чёртовой бабушке чтобы оно гладко описывалось через has
Здесь загвоздка скорее в ограниченных возможностях Eloquent, а не в плохой модели. Eloquent это надстройка над или пре-компилятор SQL. Он по определению не может дать больше, чем даёт SQL. Хотя некоторые типовые действия выглядят в нём удобно.
Всё же я надеюсь, что удастся найти хороший перевод.
Не в сети
Это понятно и я не говорю всё менять. Так, на будущее, если не знал.:) Я тут сильно экспериментировал с запросами и открыл для себя, что иногда два запроса лучше одного, а Eloquent сам может разделить одну конструкцию на несколько запросов.
Кароооче. Твой запрос перенести мне слабо, но можно попробовать написать несколько запросов.
Не в сети
Я согласен с тем что бывает удобнее несколько запросов чем один. Но данный пример я не знаю как переписать ни в один, ни в несколько запросов чтобы не было очевидного бестолкового оверхеда. PHP не должен брать на себя функцию сервера БД.
Продублировал вопрос на laracast в предельно упрощённом виде, может там подскажут.
Изменено doublevas (12.09.2019 13:21:38)
Не в сети
Я согласен с тем что бывает удобнее несколько запросов чем один. Но данный пример я не знаю как переписать ни в один, ни в несколько запросов чтобы не было очевидного бестолкового оверхеда.
ПРивет, я понимаю, что ничем тебе не помогу в моем сообщении, но могу узнать.. ?
Зачем использовать ларкин Eloquent для сложных запросов.. да и вообще для запросов.. почему бы все запросы не отправлять в RAW формате, ведь на обработку RAW запросов требуется минимальное кол-во времени (Eloquent в таком случае не нужно строить RAW строку для твоих запросов в стелочном синтаксисе.. он же все в конце концов приводит к RAW и отправляет такой запрос в БД..)
Еще одно преимущество в использовании RAW запросов - изучени и практика работы с sql синтаксисом.. ведь он всегда один и тот же.. а вот php оберток написано для него много и все они в итоге преобразют твой синтаксис в raw запрос..
Не в сети
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
Не в сети
Страницы 1