Laravel 查询生成器联合:添加 'table name' 列
Laravel Query Builder Unions: Add 'table name' column
有 3 个不同的数据库 tables articles
、reviews
、posts
,它们都有这些列:'id', 'title', 'user_id', 'created_at', 'body'
.
我正在使用 Laravel 5.6 和 yajra/laravel-datatables 包,所以我需要 "union" 这三个 table 并将其放入 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 | ... | ... |
+----+-------------+---------+------------+------+
问题是我需要知道每个记录(行)来自哪个table。
是否可以添加包含数据库 table 名称的自定义列(例如 "source")? (使用查询生成器)
+----+-------------+---------+------------+------+----------+
| id | title | user_id | created_at | body | source |
+----+-------------+---------+------------+------+----------+
| 1 | Some title | 1 | ... | ... | articles |
| 1 | Lorem ipsum | 2 | ... | ... | reviews |
| 1 | Test | 1 | ... | ... | posts |
+----+-------------+---------+------------+------+----------+
将 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
字段添加到您的结果集中
return 行的来源 table 没有函数。例如,如果你有一个 JOIN,它必须 return 一个列表,并且派生的 table 子查询等会使它变得更加复杂。
在 UNION 中执行此操作的方法是向 UNION 中的每个查询添加一个自定义列,其中包含一个用于命名 table.
的字符串常量
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 编辑的行 return。)
https://laravel.com/docs/5.6/queries#selects 显示 select-list
中自定义列的示例
所以您应该能够在您的字段中定义额外的列:
$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);
以上我没有测试过
有 3 个不同的数据库 tables articles
、reviews
、posts
,它们都有这些列:'id', 'title', 'user_id', 'created_at', 'body'
.
我正在使用 Laravel 5.6 和 yajra/laravel-datatables 包,所以我需要 "union" 这三个 table 并将其放入 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 | ... | ... |
+----+-------------+---------+------------+------+
问题是我需要知道每个记录(行)来自哪个table。 是否可以添加包含数据库 table 名称的自定义列(例如 "source")? (使用查询生成器)
+----+-------------+---------+------------+------+----------+
| id | title | user_id | created_at | body | source |
+----+-------------+---------+------------+------+----------+
| 1 | Some title | 1 | ... | ... | articles |
| 1 | Lorem ipsum | 2 | ... | ... | reviews |
| 1 | Test | 1 | ... | ... | posts |
+----+-------------+---------+------------+------+----------+
将 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
字段添加到您的结果集中
return 行的来源 table 没有函数。例如,如果你有一个 JOIN,它必须 return 一个列表,并且派生的 table 子查询等会使它变得更加复杂。
在 UNION 中执行此操作的方法是向 UNION 中的每个查询添加一个自定义列,其中包含一个用于命名 table.
的字符串常量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 编辑的行 return。)
https://laravel.com/docs/5.6/queries#selects 显示 select-list
中自定义列的示例所以您应该能够在您的字段中定义额外的列:
$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);
以上我没有测试过