雄辩的:外部查询中的别名不能在子查询中引用

时间:2019-01-28 11:03:28

标签: laravel laravel-5 eloquent

我有以下查询:

DB::table('dining_tables as dt')
        ->whereNotExists(function($query){
            $query
                ->from('booking_allocations as ba')
                ->join('time_slots as ts', 'ba.slot_id', '=', 'ts.id')
                ->where('ba.booking_date', '=', '2019-01-27')
                ->where('ts.start_time', '>=', '12:00 PM')
                ->where('ts.end_time', '<=', '1:00 PM')
                ->where('ba.table_id', '=', 'dt.id')
                ->select(DB::raw('null'));
        })
        ->where('dt.capacity', '>=', 4)
        ->select('id')
        ->limit(1)
        ->get();

注意,在外部查询中创建的别名dt在以下行的子查询中被引用:

->where('ba.table_id', '=', 'dt.id')

这给我留下了以下错误:

  

带有消息'SQLSTATE [22P02]的Illuminate / Database / QueryException:   无效的文本表示形式:7错误:的无效输入语法   整数:“ dt.id”(SQL:从“ dining_tables”中选择“ id”作为“ dt”,其中   不存在(从“ booking_allocations”中选择null作为“ ba”内部联接   “ time_slots”作为“ ba”上的“ ts”。“ slot_id” =“ ts”。“ id”,其中   “ ba”。“ booking_date” = 2019-01-27和“ ts”。“ start_time”> = 12:00 PM和   “ ts”。“ end_time” <= 1:00 PM和“ ba”。“ table_id” = dt.id)和   “ dt”。“容量”> = 4限制1)'

我花了半天的时间才能意识到此替换代码可以避免该错误:

->where('ba.table_id', '=', DB::raw('dt.id'))

注意:将DB::raw()包装在有问题的别名周围。

现在,查询将按预期工作。我想了解这里可能会发生什么。

1 个答案:

答案 0 :(得分:3)

whereNotExists在内部进行单独的查询:

https://github.com/laravel/framework/blob/5.7/src/Illuminate/Database/Query/Builder.php#L1435 https://github.com/laravel/framework/blob/5.7/src/Illuminate/Database/Query/Builder.php#L1404 https://github.com/laravel/framework/blob/5.7/src/Illuminate/Database/Query/Builder.php#L2772

dt仅对于数据库构建器的“较高”实例是已知的。

因此,db builder在您嵌套的位置将其视为字符串,并且由于ba.table_id是整数,因此无法在该上下文中使用string类型的值。

使用db raw时-它将它直接放入sql中,并按预期方式工作。