【问题标题】:Laravel subquery in from clausefrom 子句中的 Laravel 子查询
【发布时间】:2021-08-18 04:02:29
【问题描述】:

我需要在 from 子句中使用子查询,但我在 Laravel 文档中找不到这样的东西

Laravel 5.4 版

$sub = Chat::join("chats as _chats", function ($query) {
    $query->on('chats.room_id', "=", "_chats.room_id")
          ->on('chats.user_type', "<>", "_chats.user_type")
          ->on('chats.created_at', "=", DB::raw("(SELECT MIN(created_at) FROM chats WHERE created_at > '_chats.created_at')"));
    })
    ->selectRaw('TIMESTAMPDIFF(MINUTE, _chats.created_at, chats.created_at) as res')
    ->where('chats.user_type', 'pharmacy_consultant')
    ->where('chats.user_id', 26)
    ->toSql();

       
dd(
    DB::connection('mysql2')
        ->table(DB::raw("({$sub}) as sub"))
        ->select('res')
        ->get()
);
(2/2) QueryException SQLSTATE[HY000]: General error: 2031 
(SQL: select `res` from (select TIMESTAMPDIFF(MINUTE, _chats.created_at, chats.created_at) as res
from `chats` inner join `chats` as `_chats` on `chats`.`room_id` = `_chats`.`room_id` and `chats`.`user_type` <> `_chats`.`user_type` and `chats`.`created_at` = 
(SELECT MIN(created_at) FROM chats WHERE created_at > _chats.created_at) where `chats`.`user_type` = ? and `chats`.`user_id` = ?) as sub)

【问题讨论】:

    标签: mysql laravel laravel-5


    【解决方案1】:

    尝试传递构建器实例而不是原始查询。

    // $sub = Query Builder instance
    $sub = Chat::join("chats as _chats", function ($query) {
        $query->on('chats.room_id', "=", "_chats.room_id")
              ->on('chats.user_type', "<>", "_chats.user_type")
              ->on('chats.created_at', "=", DB::raw("(SELECT MIN(created_at) FROM chats WHERE created_at > '_chats.created_at')"));
        })
        ->selectRaw('TIMESTAMPDIFF(MINUTE, _chats.created_at, chats.created_at) as res')
        ->where('chats.user_type', 'pharmacy_consultant')
        ->where('chats.user_id', 26);
        // ->toSql();
    
    DB::connection('mysql2')
        ->table($sub, "sub")
        ->select('res')
        ->get()
    

    既然您在最终查询中除了选择之外什么都不做,为什么不直接在第一个查询中做呢?

    $results = Chat::join("chats as _chats", function ($query) {
        $query->on('chats.room_id', "=", "_chats.room_id")
              ->on('chats.user_type', "<>", "_chats.user_type")
              ->on('chats.created_at', "=", DB::raw("(SELECT MIN(created_at) FROM chats WHERE created_at > '_chats.created_at')"));
        })
        ->selectRaw('TIMESTAMPDIFF(MINUTE, _chats.created_at, chats.created_at) as res')
        ->where('chats.user_type', 'pharmacy_consultant')
        ->where('chats.user_id', 26)
        ->select('res')
        ->get();
    

    【讨论】:

    • 传递构建器实例不起作用,我也无法在第一个查询中选择,因为它是子查询的一部分
    【解决方案2】:

    使其适合您的需求:

    ...
    ->addSelect([res' => ChartModel::select('//whatever') 
       ->whereColumn('//sub-query column', 'parent-table.field') 
       ->whereColumn('//and whatever')
       ->latest() 
       ->take(1)
    )]
    ...
    

    【讨论】:

    • 谢谢,但忘了提到我编辑帖子的 Laravel 版本,这是从 Laravel 6 开始添加的,我使用的是 5.4。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    相关资源
    最近更新 更多