【thinkphp知识】thinkphp 使用union链式操作合并两个或多个 SELECT 语句的结果集,新增不存在的字段,并赋予默认值

简介: 【thinkphp知识】thinkphp 使用union链式操作合并两个或多个 SELECT 语句的结果集,新增不存在的字段,并赋予默认值

前言

之前有做过laravel使用union的:laravelDb查询数据库使用union合并两个不相关的表,新增不存在的字段,并赋予默认值

那么thinkphp又要如何做呢?

我们可以先查看官方文档:https://static.kancloud.cn/manual/thinkphp5/118084

使用案例

Db::field('name')
   ->table('think_user_0')
   ->union(function($query){
    $query->field('name')->table('think_user_1');
     })
   ->union(function($query){
    $query->field('name')->table('think_user_2');
     })
   ->select();

当然,官方的这种办法是可以实现的,但是明显还不够优雅,我们可以结合buildSql构造子查询一起来使用:https://static.kancloud.cn/manual/thinkphp5/135185

使用例子

$subQuery = Db::table('think_user')
    ->field('id,name')
    ->where('id','>',10)
    ->buildSql();

实际案例

需求分析

今天有一个需求,需要写一个全局搜索接口,系统的数据很多,包括新闻,文章,协会专家,供应采购等等数据,覆盖多个表的数据,每部分的内容都太一样,当然你可以直接简单粗暴的使用遍历查询每个表的数据,再进行合并,但是这样明显不够方便,开销也大,而且肯定还会涉及数据分页,手写分页也是挺麻烦的,所以我们可以选择使用union直接一步到位,UNION操作就是用于合并两个或多个 SELECT 语句的结果集。

几个数据库表结构

代码实现

'' AS title表示新增不存在的字段,并赋予默认值为空字符

//全局搜索接口
public function search()
{
    $request = request()->post();
    $limit = $request['limit'] ?? 10;
    $title = $request['title'] ?? '';

    //菜单导航:1=新闻中心,2=网上办事,3=法规标准,4=协会专家,5=供应,6=采购
    $where = [];
    if ($title) $where['name'] = ['like', "%" . $title . "%"];
    $sql4 = DB::name("expert")->field("id, name, '' AS title, tags, '' AS url , FROM_UNIXTIME(createtime) as createtime, 4 AS menu")
        ->where($where)
        ->buildSql();
    $sql5 =DB::name("supply")->field("id, name, '' AS title, tags, '' AS url , FROM_UNIXTIME(createtime) as createtime, 5 AS menu")
        ->where($where)
        ->buildSql();

    $where = [];
    if ($title) $where['title'] = ['like', "%" . $title . "%"];
    $sql1 = DB::name("news")->field("id, '' AS name, title, tags, '' AS url , FROM_UNIXTIME(createtime) as createtime, 1 AS menu")
        ->where($where)
        ->buildSql();
    $sql2 = DB::name("work")->field("id, '' AS name, title, tags, url, FROM_UNIXTIME(createtime) as createtime, 2 AS menu")
        ->where($where)
        ->buildSql();
    $sql3 = DB::name("laws")->field("id, '' AS name, title, tags, '' AS url , FROM_UNIXTIME(createtime) as createtime, 3 AS menu")
        ->where($where)
        ->buildSql();
    $sql6 = DB::name("purchase")->field("id, '' AS name, title, tags, '' AS url, FROM_UNIXTIME(createtime) as createtime, 6 AS menu") 
        ->where($where);
    //合并
    $sql = $sql6->union([$sql1, $sql2, $sql3, $sql4, $sql5])->buildSql();
    $data = Db::table($sql.' a')->order("a.createtime desc")->paginate($limit);
        $this->success('获取成功', $data);
    }

结果

注意

UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同

UNION与UNION ALL的区别

当使用 UNION 时,MySQL 会把结果集中重复的记录删掉,而使用 UNION ALL ,MySQL 会把所有的记录返回,且效率高于 UNION。

想使用UNION ALL也非常简单

Db::field('name')
    ->table('think_user_0')
    ->unionAll('SELECT name FROM think_user_1')
    ->unionAll('SELECT name FROM think_user_2')
    ->select();

或者

Db::field('name')
    ->table('think_user_0')
    ->union(['SELECT name FROM think_user_1', 'SELECT name FROM think_user_2'], true)
    ->select();
目录
相关文章
|
移动开发
钉钉H5微应用配置IP,应用首页地址报错:app url exceeds max length limit,这个怎么处理?
钉钉H5微应用配置IP,应用首页地址报错:app url exceeds max length limit,这个怎么处理?
1786 0
|
10月前
|
安全 PHP 数据库
告别繁琐循环:用array_map与array_filter优雅处理PHP数组
告别繁琐循环:用array_map与array_filter优雅处理PHP数组
538 132
|
11月前
|
SQL 人工智能 运维
一场由AI拯救的数据重构之战
本文以数据研发工程师小D的日常困境为切入点,探讨如何借助AI技术提升数据研发效率。通过构建“数研小助手”智能Agent,覆盖需求评估、模型评审、代码开发、运维排查等全链路环节,结合大模型能力与内部工具(如图治MCP、D2 API),实现影响分析、规范检查、代码优化与问题定位的自动化,系统性解决传统研发中耗时长、协作难、维护成本高等痛点,推动数据研发向智能化跃迁。
604 29
一场由AI拯救的数据重构之战
|
前端开发 PHP
ThinkPHP6,视图的安装及模板渲染和变量赋值 view::fetch() ,view::assgin() ,助手函数
本文介绍了ThinkPHP6中视图的安装和使用,包括通过`composer`安装`topthink/think-view`,使用`view::fetch()`进行模板渲染和变量赋值,以及使用`view::assign()`进行全局模板变量赋值。还提到了助手函数作为`view::fetch()`和`view::assign()`的封装组合,但效率较低。
ThinkPHP6,视图的安装及模板渲染和变量赋值 view::fetch() ,view::assgin() ,助手函数
|
SQL 数据挖掘 大数据
如何在 SQL Server 中使用 `OFFSET` 和 `FETCH`
【8月更文挑战第10天】
4074 8
|
JavaScript 前端开发 API
Vue3基础(十yi)___常用生命周期函数___setup___onMounted___onUpdated
本文介绍了Vue 3中的常用生命周期函数,包括`setup`、`onBeforeMount`、`onMounted`、`onBeforeUpdate`、`onUpdated`、`onBeforeUnmount`和`onUnmounted`,并解释了它们与Vue 2生命周期钩子的对应关系。文章通过代码示例展示了这些生命周期钩子在组件中的使用时机和场景。
628 0
|
程序员 PHP
老程序员分享:PHPstripos()、strripos()和strrpos()使用方法和区别
老程序员分享:PHPstripos()、strripos()和strrpos()使用方法和区别
572 0
|
JavaScript 前端开发 索引
Vue3基础之v-if条件与 v-for循环
Vue3基础之v-if条件与 v-for循环
651 0
|
安全
360极速浏览器以及360安全浏览器在兼容模式下验证码图片显示不来,但是极速模式可以显示?
360极速浏览器以及360安全浏览器在兼容模式下验证码图片显示不来,但是极速模式可以显示?
1009 0
360极速浏览器以及360安全浏览器在兼容模式下验证码图片显示不来,但是极速模式可以显示?
|
前端开发 JavaScript 开发者
vue3页面调接口时加载卡住不响应
vue3页面调接口时加载卡住不响应
3219 0