laravel查询生成器联合:添加“table name”列

irlmq6kh  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(360)

有3个不同的数据库表 articles , reviews , posts 它们都有这些列: 'id', 'title', 'user_id', 'created_at', 'body' .
我使用的是laravel5.6和yajra/laraveldatatables包,所以我需要“联合”这三个表并将其放入jquerydatatables中。我用的是拉威尔的 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 | ...        | ...  |
+----+-------------+---------+------------+------+

问题是我需要知道每个记录(行)来自哪个表。是否可以添加一个自定义列(例如“source”),其中包含db表名(使用查询生成器)

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

bmvo0sr51#

添加 DB::raw 自定义字段 fields 数组在 select 比如:

$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 结果集的字段

3pmvbmvn

3pmvbmvn2#

没有函数返回作为行源的表。例如,如果您有一个连接,它就必须返回一个列表,并且派生表子查询等会使它更加复杂。
在联合中执行此操作的方法是,使用用于命名表的字符串常量向联合中的每个查询添加一个自定义列。

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

(您只需要在第一个查询中定义列别名,它将应用于联合返回的所有行。)
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);

我没有测试过上面的。

相关问题