【问题标题】:Laravel DB query builder - using multiple 'from' with aliasesLaravel DB 查询构建器 - 使用多个带有别名的“来自”
【发布时间】:2021-03-25 10:52:30
【问题描述】:

我有以下查询:

SELECT 
    cd_4.userfield, 
    COUNT( DISTINCT (Case When cd_4.disposition_Last =  'ANSWERED' Then cd_4.uniqueid ELSE NULL END) ) AS Answered_Count, 
    COUNT( DISTINCT (Case When cd_4.disposition_Last <> 'ANSWERED' Then cd_4.uniqueid ELSE NULL END) ) AS Not_Answered_Count 
FROM (
    SELECT  
        cd_2.Userfield,
        cd_2.Start_Date,
        cd_2.uniqueid,
        cd_2.Row_Id_Max, 
        cd_3.disposition AS disposition_Last 
    FROM (
        SELECT 
            cd_1.userfield,
            cd_1.Start_Date,
            cd_1.uniqueid,
            MAX(cd_1.Row_Id) AS Row_Id_Max 
        FROM 
            cdrnew As cd_1
        WHERE (
            cd_1.Start_Date BETWEEN '2020-12-01' AND '2020-12-10'
        )
        AND cd_1.userfield = 'Inbound' 
        GROUP BY 
            cd_1.userfield,
            cd_1.Start_Date,
            cd_1.uniqueid
    ) AS cd_2 
    INNER JOIN cdrnew As cd_3
    ON cd_3.Row_Id = cd_2.Row_Id_Max
    WHERE (
        cd_3.Start_Date BETWEEN '2020-12-01' AND '2020-12-10'
    )
    AND cd_3.userfield = 'Inbound'
) AS cd_4 ;

我有 4 个别名用于上述表 cdrnew,名为 cd_1、cd_2、cd_3 cd_4

我想使用 laravel 查询构建器实现同样的目的:

我尝试了以下 laravel 查询:

   $sqlquery = DB::table('cdrnew')->select('cdrnew.userfield')
        ->addSelect(DB::raw('COUNT(DISTINCT (
      Case When cdrnew.disposition = "ANSWERED" Then cdrnew.uniqueid ELSE NULL END
    )) as Answered_Count'))
        ->addSelect(DB::raw('COUNT(DISTINCT (
      Case When cdrnew.disposition <> "ANSWERED" Then cdrnew.uniqueid ELSE NULL END
    )) as Not_Answered_Count'))
         ->addSelect(DB::raw('cdrnew.Start_Date, cdrnew.uniqueid, MAX(cdrnew.Row_Id) AS Row_Id_Max'))
         ->whereBetween('cdrnew.Start_Date', ["2020-12-12", "2020-12-15"])
        ->groupBy('userfield','Start_Date','uniqueid')
        ->join('cdrnew AS cd_1',"cdrnew.Row_Id", "=", "cd_1.Row_Id") 
       ->limit(10)->get();

但我只能创建两个别名。一个是 DB::Table(cdrnew) 的默认值,另一个是 join(cd_1) 的默认值。我们如何在 laravel 中创建多个 'from' 语句以及不同的别名?

例如:

  1. 从 cdrnew 作为 cd_1(别名 1)。
  2. 来自 cdrnew 作为 cd_2(别名 2)。
  3. 来自 cdrnew 作为 cd_3(别名 3)。
  4. .....等等

【问题讨论】:

    标签: php laravel laravel-5 laravel-query-builder


    【解决方案1】:

    tablefrom 方法的工作方式类似。它们可以接受 2 个参数,表(可以是 ClosureBuilder 实例)和别名。据我所知,唯一的区别是table 必须是DB:: 之后调用的第一个方法

    例如下面的查询

    SELECT * FROM (
        SELECT * FROM table1 WHERE condition = "something"
    ) AS alias1
    

    可以用Closure这样写。

    DB::table(function ($subquery) {
        return $subquery->from('table1')->where('condition', 'something');
    }, 'alias')
    ->get();
    // Or using PHP7.4 short Closures
    DB::table(fn($subquery) => $subquery->from('table1')->where('condition', 'something'), 'alias')->get();
    

    或者像这样使用Builder 实例。

    $alias = DB::table('table1')->where('condition', 'something');
    DB::table($alias, 'alias')->get();
    

    因此您的查询可以使用构建器翻译为以下内容

    $cd_2 = DB::table('cdrnew, cd_1')
        ->select(
            'cd_1.userfield',
            'cd_1.Start_Date',
            'cd_1.uniqueid',
        )
        ->selectRaw('MAX(cd_1.Row_Id) AS Row_Id_Max')
        ->whereBetween('cd_1.Start_Date', ['2020-12-01', '2020-12-10'])
        ->where('cd_1.userfield', 'Inbound')
        ->groupBy(
            'cd_1.userfield',
            'cd_1.Start_Date',
            'cd_1.uniqueid'
        );
    
    $cd_4 = DB::table($cd_2, 'cd_2')
        ->select(
            'cd_2.Userfield',
            'cd_2.Start_Date',
            'cd_2.uniqueid',
            'cd_2.Row_Id_Max', 
            'cd_3.disposition AS disposition_Last'
        )
        ->join('cdrnew AS cd_3', 'cd_3.Row_Id', '=', 'cd_2.Row_Id_Max')
        ->whereBetween('cd_3.Start_Date', ['2020-12-01', '2020-12-10'])
        ->where('cd3.userfield', 'Inbound');
    
    $query = DB::table($cd_4, 'cd_4')
        ->select('cd_4.userfield')
        ->selectRaw('COUNT(DISTINCT(CASE WHEN cd_4.disposition_Last = "ANSWERED" THEN cd_4.uniqueid ELSE NULL END)) AS Answered_Count')
        ->selectRaw('COUNT(DISTINCT(CASE WHEN cd_4.disposition_Last <> "ANSWERED" THEN cd_4.uniqueid ELSE NULL END)) AS Not_Answered_Count');
    
    // Uncomment next line to see the query produced. It should be the same you posted in your question.
    // dd($query->toSql());
    $results = $query->get();
    

    或者像这样使用Closures

    $query = DB::table(function ($cd_4) {
        return $cd_4->from(function ($cd_2) {
            return $cd_2->from('cdrnew, cd_1')
            ->select(
                'cd_1.userfield',
                'cd_1.Start_Date',
                'cd_1.uniqueid',
            )
            ->selectRaw('MAX(cd_1.Row_Id) AS Row_Id_Max')
            ->whereBetween('cd_1.Start_Date', ['2020-12-01', '2020-12-10'])
            ->where('cd_1.userfield', 'Inbound')
            ->groupBy(
                'cd_1.userfield',
                'cd_1.Start_Date',
                'cd_1.uniqueid'
            );
        }, 'cd_2')
        ->select(
            'cd_2.Userfield',
            'cd_2.Start_Date',
            'cd_2.uniqueid',
            'cd_2.Row_Id_Max', 
            'cd_3.disposition AS disposition_Last'
        )
        ->join('cdrnew AS cd_3', 'cd_3.Row_Id', 'cd_2.Row_Id_Max')
        ->whereBetween('cd_3.Start_Date', ['2020-12-01', '2020-12-10'])
        ->where('cd3.userfield', 'Inbound');
    }, 'cd_4')
    ->select('cd_4.userfield')
    ->selectRaw('COUNT(DISTINCT(CASE WHEN cd_4.disposition_Last = "ANSWERED" THEN cd_4.uniqueid ELSE NULL END)) AS Answered_Count')
    ->selectRaw('COUNT(DISTINCT(CASE WHEN cd_4.disposition_Last <> "ANSWERED" THEN cd_4.uniqueid ELSE NULL END)) AS Not_Answered_Count');
    
    // Uncomment next line to see the query produced. It should be the same you posted in your question.
    // dd($query->toSql());
    $results = $query->get();
    

    据我所知,生成的查询是相同的。

    【讨论】:

    • 如果 MySQL 抱怨 GROUP BY 子句,请确保在 config/database.php 中将严格模式设置为 false
    猜你喜欢
    • 2017-06-29
    • 2018-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    相关资源
    最近更新 更多