Laravel Eloquent - выберите наибольшее значение для каждого типа - объединение, максимальное () и группирование по - PullRequest
1 голос
/ 05 марта 2020

Я все еще учусь laravel и красноречив, и у меня есть небольшая проблема ...

У меня есть три таблицы:

Schema::create('fishes', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->bigInteger('user_id')->unsigned();
                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
                $table->bigInteger('type_id')->unsigned();
                $table->foreign('type_id')->references('id')->on('fish_types')->onDelete('cascade');
                $table->float('length');
});

Schema::create('fish_types', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('name')->unique();
                $table->string('name_raw')->unique();
});

Schema::create('photos', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('photoable_type');
                $table->string('photoable_id');
                $table->string('path');
});

У меня есть модель Fi sh и отношения с fi sh типами и фотографиями. И его работа, все хорошо, например:

$f = Fish::with('photos', 'fishery', 'type')->when($filters['userId'], function ($query) use ($filters) {
    return $query->where('user_id', $filters['userId']);
});

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

У меня mysql вопрос (да, это плохо, но мое присоединение к eloquent не работает :():

$sql = "
SELECT id
  FROM fishes f1
  JOIN 
     ( SELECT type_id
            , MAX(`length`) AS pb
          FROM fishes
          where user_id = 6
          GROUP BY type_id
     ) AS f2
    ON f1.type_id = f2.type_id 
   and f2.pb = f1.length 
 where f1.user_id = 6
";

Итак, у меня есть идентификатор файла sh - но что дальше? Тот же запрос "whereIn (Column_name, Array)"?

$sth = DB::getPdo()->prepare($sql);
$sth->execute();
$quy = $sth->fetchAll(\PDO::FETCH_COLUMN, 0);
$f = Fish::with('photos', 'fishery', 'type')
          ->where('user_id', 6)
          ->whereIn('id', $quy)->get();

укороченный Fi sh Модель:

class Fish extends Model
{
    public function type()
    {
        return $this->belongsTo('App\Models\FishType');
    }

    public function fishery()
    {
        return $this->belongsTo('App\Models\Fishery');
    }

    public function photos()
    {
        return $this->morphMany('App\Models\Photo', 'photoable');
    }

    public function user()
    {
        return $this->belongsTo('App\User');
    }
}

Фотографии Модель и миграция:

 public function up()
    {
        Schema::create('photos', function (Blueprint $table) {

            $table->bigIncrements('id');
            $table->string('photoable_type');
            $table->bigInteger('photoable_id');
            $table->string('path');

        });
    }


class Photo extends Model
{

    public function photoable()
    {
        return $this->morphTo();
    }
}

Обычно это работает, но, может быть, я делаю это неправильно? Как сделать это лучше? Можете ли вы мне помочь? :)

T.

1 Ответ

0 голосов
/ 05 марта 2020

Вы выполняете два запроса, но это можно сделать одним запросом. Попробуйте это

Fish::with('photos', 'fishery', 'type')
    ->join(DB::raw('( SELECT type_id
            , MAX(`length`) AS pb
          FROM fishes
          where user_id = 6
          GROUP BY type_id
     ) AS f2'),function($join){
    $join->on('fishes.type_id','=','f2.type_id')
         ->on('fishes.length','=','f2.pb');
    })
    ->where('user_id', 6)->get();

Вместо

$sql = "
SELECT id
  FROM fishes f1
  JOIN **strong text**
     ( SELECT type_id
            , MAX(`length`) AS pb
          FROM fishes
          where user_id = 6
          GROUP BY type_id
     ) AS f2
    ON f1.type_id = f2.type_id 
   and f2.pb = f1.length 
 where f1.user_id = 6
";

$sth = DB::getPdo()->prepare($sql);
$sth->execute();
$quy = $sth->fetchAll(\PDO::FETCH_COLUMN, 0);
$f = Fish::with('photos', 'fishery', 'type')
          ->where('user_id', 6)
          ->whereIn('id', $quy)->get();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...