【问题标题】:Eloquent representation of SQL querySQL查询的雄辩表示
【发布时间】:2018-07-01 11:32:23
【问题描述】:

您好,我在我的项目中使用 Eloquent 和 Slim。我创建了模型:Reservation、ReservationCottage(链接表)、具有关系的 Cottage:对 N - N 等小屋的预订,现在我想知道如何更改 Eloquent 查询的 SQL 查询。

class Reservation extends Model
{
    protected $table = 'reservations';
    protected $fillable = [
        'start',
        'end',
    ];
    public function cottages()
    {
        return $this->belongsToMany(Cottage::class);
    }
    public function user()
    {
        return $this->belongsTo(User::class);
    }
    public function reservationStatus()
    {
        return $this->belongsTo(ReservationStatus::class);
    }
    public function payments()
    {
        return $this->hasMany(Payment::class);
    }
}

class ReservationCottage extends Model
{
    protected $table = 'reservation_cottages';

    public function guests()
    {
        return $this->hasMany(Guest::class);
    }
}

class Cottage extends Model
{
    protected $table = 'cottages';

    protected $fillable = [
        'name',
        'capacity',
        'description',
        'base_price',
    ];

    public function additions()
    {
        return $this->belongsToMany(Addition::class);
    }
    public function cottagePeriods()
    {
        return $this->hasMany(CottagePeriod::class);
    }
    public function periods()
    {
        return $this->belongsToMany(Period::class);
    }
    public function reservations()
    {
        return $this->belongsToMany(Reservation::class);
    }
    public function cottageStatus()
    {
        return $this->belongsTo(CottageStatus::class);
    }

这是查询预订表中是否有周期(从@ArrivalDate@DepartureDate):

SELECT cottage.name FROM cottages WHERE id NOT IN (
    SELECT cottage_id 
    FROM   reservation_cottages RC
           JOIN reservations R
               ON R.id = RC.reservation_id
    WHERE  (r.start <= @ArrivalDate AND R.end >= @ArrivalDate)
           OR (R.start < @DepartureDate AND R.end >= @DepartureDate )
           OR (@ArrivalDate <= R.start AND @DepartureDate >= R.start)

【问题讨论】:

  • 也许我会改用查询生成器。
  • 也许更有用的答案? ;)

标签: php mysql sql laravel eloquent


【解决方案1】:

好的,这是一个(希望)更有帮助的答案。在我的示例中,我使用 Laravel 查询构建器来创建这样一个复杂的查询。示例:

$rows = DB::table('cottages')
    ->select('cottage.name')
    ->from('cottages')
    ->whereNotIn('id', function (Builder $query) {
        $query->select('cottage_id')
            ->from('reservation_cottages AS RC')
            ->join('reservations AS R', 'R.id', '=', 'RC.reservation_id')
            ->whereColumn('r.start', '<=', 'ArrivalDate')
            ->whereColumn('R.end', '>=', 'ArrivalDate')
            ->orWhere(function (Builder $query) {
                $query->whereColumn('R.start', '<', 'DepartureDate')
                    ->whereColumn('R.end', '>=', 'DepartureDate');
            })
            ->orWhere(function (Builder $query) {
                $query->whereColumn('ArrivalDate', '<=', 'R.start')
                    ->whereColumn('DepartureDate', '>=', 'R.start');
            });
    })->get();

生成的 SQL:

SELECT 
  `cottage`.`name` 
FROM
  `cottages` 
WHERE `id` NOT IN 
(SELECT 
    `cottage_id` 
    FROM
    `reservation_cottages` AS `RC` 
    INNER JOIN `reservations` AS `R` ON `R`.`id` = `RC`.`reservation_id` 
    WHERE `r`.`start` <= `ArrivalDate` 
    AND `R`.`end` >= `ArrivalDate` 
    OR (
        `R`.`start` < `DepartureDate` 
        AND `R`.`end` >= `DepartureDate`
       ) 
    OR (
        `ArrivalDate` <= `R`.`start` 
        AND `DepartureDate` >= `R`.`start`
));

【讨论】:

    猜你喜欢
    • 2018-10-02
    • 2015-07-07
    • 2018-01-26
    • 2014-04-12
    • 2021-07-23
    • 1970-01-01
    • 2017-11-11
    • 2020-01-14
    相关资源
    最近更新 更多