【问题标题】:how to convert this SQL query to eloquent in Laravel如何在 Laravel 中将此 SQL 查询转换为 eloquent
【发布时间】:2021-10-04 15:09:38
【问题描述】:

我正在尝试将此 SQL 查询转换为 Laravel 中的 Eloquent

将 SQL 代码转换为 Eloquent

SELECT
  session_id,
  SUM(points) AS total_points 
FROM
  (
    SELECT
      session_id,
      spent_points AS points 
    FROM
      session_details 
    WHERE
      session_id IN 
      (
        " - Meagevy6y9ukbmFXvB7",
        " - Meak6dG9iqvHWfAGQvy"
      )
    UNION ALL
    SELECT
      session_id,
      price_points 
    FROM
      template_sales 
    WHERE
      session_id IN 
      (
        " - Meagevy6y9ukbmFXvB7",
        " - Meak6dG9iqvHWfAGQvy"
      )
  )
  t 
GROUP BY
  session_id

我在 Laravel 中的代码但不工作

$ids = ["-Meagevy6y9ukbmFXvB7","-Meak6dG9iqvHWfAGQvy"];
$query = DB::table('session_details')
    ->select('session_id',DB::raw('SUM(points) AS total_points FROM ( SELECT session_id, spent_points AS points FROM session_details
    WHERE session_id IN ("'.$ids.'") UNION ALL SELECT session_id,price_points FROM template_sales WHERE session_id IN ("'.$ids.'") ) t GROUP BY session_id'))
->get();

【问题讨论】:

    标签: php sql laravel eloquent laravel-7


    【解决方案1】:

    我建议你使用 Eloquent 模型和 Eloquent 关系来使查询更具可读性。

    在终端中执行以下命令来创建一个新模型:

    php artisan make:model SessionDetail
    

    在 /app/Models(或您的模型所在的任何文件夹)中打开 Laravel 为您生成的文件,并通过将以下属性放入模型类中来设置模型中的表:public $table = "session_details";

    如果您的模型不使用或具有通常是 created_at 和 updated_at 的 Laravel 时间戳,您也可以使用此属性在模型中禁用它们:public $timestamps = false;

    之后,通过在终端中执行以下命令来创建生成另一个模型:

    php artisan make:model TemplateSale
    

    再次按照相同的说明进行操作,但这次将表名更改为template_sales

    完成此操作后,进入 SessionDetail 模型并使用以下代码与 TemplateSale 模型建立关系(这必须在属性下方的模型类中):

    public function template_sales() {
       return $this->hasMany(TemplateSale::class);
    }
    

    之后,您可以用这行代码替换您的查询:

    $query = \App\Models\SessionDetail::select("session_id", "SUM(points) as total_points")->whereIn("session_id", $ids)->get();
    

    要从该查询中获取模板销售额,您必须使用 $query->template_sales;

    如果我有什么问题,请告诉我,我会尽快修复它

    【讨论】:

      【解决方案2】:

      查询中的所有操作都有可用的文档。

      • 对于选定的列,使用select('column1', 'column2', ...)
      • 对于选定的聚合列,使用selectRaw('sum(column) as column')
      • 对于WHERE column IN (...),使用whereIn('column', $array)
      • 对于子查询表,使用ClosuresBuilder 类(DB::table(fn($q) => ... , alias)DB::table($builder, alias)
      • 对于UNION ALL,使用unionAll(),其语法与子查询表相同。

      选项 1:闭包

      $ids = ["-Meagevy6y9ukbmFXvB7","-Meak6dG9iqvHWfAGQvy"];
      $query = DB::table(function ($sub) use ($ids) {
              $sub->select('session_id', 'spent_points as points')
                  ->from('session_details')
                  ->whereIn('session_id', [1,2])
                  ->unionAll(function ($union) use ($ids) {
                      $union->select('session_id', 'price_points')
                            ->from('template_sales')
                            ->whereIn('session_id', $ids);
                  });
          }), 't')
          ->select('session_id')
          ->selectRaw('sum(points) as total_points')
          ->groupBy('session_id')
          ->get();
      

      选项 2:构建器(或从内向外翻译子查询)

      $ids = ["-Meagevy6y9ukbmFXvB7","-Meak6dG9iqvHWfAGQvy"];
      
      $union = DB::table('template_sales')
          ->select('session_id', 'price_points')
          ->whereIn('session_id', $ids);
      
      $sub = DB::table('session_details')
          ->select('session_id', 'spent_points as points')
          ->whereIn('session_id', $ids)
          ->unionAll($union);
      
      $query = DB::table($sub, 't')
          ->select('session_id')
          ->selectRaw('sum(points) as total_points')
          ->groupBy('session_id')
          ->get();
      

      选择你喜欢的。两者都评估为您发布的相同查询。

      【讨论】:

        猜你喜欢
        • 2021-09-11
        • 1970-01-01
        • 2018-10-10
        • 1970-01-01
        • 1970-01-01
        • 2020-10-03
        • 1970-01-01
        • 1970-01-01
        • 2015-02-24
        相关资源
        最近更新 更多