【问题标题】:Laravel Query Builder Unions: Add 'table name' columnLaravel 查询生成器联合:添加“表名”列
【发布时间】:2019-01-28 03:32:42
【问题描述】:

有 3 个不同的数据库表 articlesreviewsposts,它们都有这些列:'id', 'title', 'user_id', 'created_at', 'body'

我正在使用 Laravel 5.6 和 yajra/laravel-datatables 包,所以我需要“联合”这三个表并将其放入 jQuery DataTables 中。 为此,我使用 Laravel 的 union 查询构建器方法:

    $fields = [
        'id',
        'title',
        'user_id', 
        'created_at',
        'body'
    ];

    $articles = DB::table('articles')->select($fields);
    $reviews = DB::table('reviews')->select($fields);
    $posts = DB::table('posts')->select($fields);

    $union = $articles->union($reviews)->union($posts)->get();

    dd($union);

...这很好用,结果如下所示:

+----+-------------+---------+------------+------+
| id |    title    | user_id | created_at | body |
+----+-------------+---------+------------+------+
|  1 | Some title  |       1 | ...        | ...  |
|  1 | Lorem ipsum |       2 | ...        | ...  |
|  1 | Test        |       1 | ...        | ...  |
+----+-------------+---------+------------+------+

问题是我需要知道每条记录(行)来自哪个表。 是否可以添加包含数据库表名称的自定义列(例如“源”)? (使用查询生成器)

+----+-------------+---------+------------+------+----------+
| id |    title    | user_id | created_at | body |  source  |
+----+-------------+---------+------------+------+----------+
|  1 | Some title  |       1 | ...        | ...  | articles |
|  1 | Lorem ipsum |       2 | ...        | ...  | reviews  |
|  1 | Test        |       1 | ...        | ...  | posts    |
+----+-------------+---------+------------+------+----------+

【问题讨论】:

    标签: mysql laravel laravel-5 union laravel-query-builder


    【解决方案1】:

    DB::raw 自定义字段添加到select 内的fields 数组中,例如:

    $articles = DB::table('articles')->select(array_merge($fields, [DB::raw('"articles" as source')]));
    $reviews = DB::table('reviews')->select(array_merge($fields, [DB::raw('"reviews" as source')]));
    $posts = DB::table('posts')->select(array_merge($fields, [DB::raw('"posts" as source')]));
    

    这应该将source 字段添加到您的结果集中

    【讨论】:

      【解决方案2】:

      没有返回作为行源的表的函数。例如,如果您有一个 JOIN,它将必须返回一个列表,并且派生表子查询等会进一步复杂化。

      在 UNION 中执行此操作的方法是为 UNION 中的每个查询添加一个自定义列,其中包含一个用于命名表的字符串常量。

      SELECT 'articles' as table_name, id, title, user_id, created_at, body
      FROM articles
      UNION
      SELECT 'reviews', id, title, user_id, created_at, body
      FROM reviews
      UNION
      SELECT 'posts', id, title, user_id, created_at, body
      FROM posts
      

      (您只需要在第一个查询中定义列别名,它将应用于UNION返回的所有行。)

      https://laravel.com/docs/5.6/queries#selects 显示了选择列表中自定义列的示例

      所以你应该能够在你的字段中定义额外的列:

      $common_fields = [
          'id',
          'title',
          'user_id', 
          'created_at',
          'body'
      ];
      
      $fields = array_merge(["articles as table_name"], $common_fields)
      $articles = DB::table('articles')->select($fields);
      
      $fields = array_merge(["reviews"], $common_fields)
      $reviews = DB::table('reviews')->select($fields);
      
      $fields = array_merge(["posts"], $common_fields)
      $posts = DB::table('posts')->select($fields);
      

      我没有测试过以上。

      【讨论】:

      • 感谢您的详细回答,您的回答是正确的,但它不起作用(我收到Column not found... 错误)...您只需要像@Seva Kalashnikov 那样使用DB::raw他的回答。再次,非常感谢!
      猜你喜欢
      • 2016-11-03
      • 1970-01-01
      • 2022-01-23
      • 2019-02-02
      • 2019-06-25
      • 2016-09-06
      • 2019-08-23
      • 2013-08-07
      • 2015-07-10
      相关资源
      最近更新 更多