ThinkPHP5,使用unionAll取出两个毫无相关字段表的数据且分页

2023-09-22 11:56:45

一:首先来了解一下 union 和 unionAll

1:取结果的并集,是否去重

  1. union:对两个结果集进行并集操作,不包括重复行,相当于distinct,同时进行默认规则的排序;

  2. unionAll:对两个结果集进行并集操作,包括重复行,即所有的结果全部显示,不管是不是重复;

2:获取结果后的操作,是否排序

  1. union:会对获取的结果进行排序操作。

  2. unionAll:不会对获取的结果进行排序操作 。

3:通过下面例子来粗略了解一下

eg1:

select * from A where id < 5
union
select * from A where id > 3 and id < 6;

第一句获取:id=1234 结果集
第二句获取:id=45 结果集
总结果集为:123445
但因为 union 会去重所以最终结果集为:12345

eg2:

select * from A where id < 5
union all
select * from A where id > 3 and id < 6;

第一句获取:id=1234 结果集
第二句获取:id=45 结果集
总结果集为:123445
union all 不会去重所以最终结果集为:123445

4:总结

union all 只是合并查询结果,并不会进行去重和排序操作,在没有去重的前提下,使用 union all 的执行效率比 union 高。

二:ThinkPHP对 UNION 和 UNIONALL 的操作说明

UNION 操作作用于合并两个或多个 SELECT 语句的结果集。

使用示例:

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

闭包用法:

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();

或者

Db::field('name')
    ->table('think_user_0')
    ->union([
        'SELECT name FROM think_user_1',
        'SELECT name FROM think_user_2',
    ])
    ->select();

支持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();

每个union方法相当于一个独立的SELECT语句。

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

示例:
通过下面的示例来具体深入了解

现在有两个表article表和notice

article表结构如下:
在这里插入图片描述
notice表结构如下:
在这里插入图片描述

需求:通过模糊查询标题(title)和内容(content)来综合获取article表和notice表的数据并且分页
两个表没有任何的关联字段,且字段数也不一样,这时候考虑使用 unionALL

$notice_array = ArticleModel::field('id,title,content,cover_img,type,video_width,video_height,video_duration,created_at,updated_at')
            ->where('title|content','LIKE','%'.$search_value.'%')
            ->unionAll("select id,title,content,created_at,updated_at from hq_notice where CONCAT(title, content) like '%$search_value%'")
            ->limit($start,$end)
            ->order('updated_at','desc')
            ->select()
            ->each(function ($item,$key){
                $item['content'] = filterContent($item['content']);
            });

这时候会出现如下报错:

SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns

两个表获取的列的数量不一样

根据需求还需要判断类型,此时先将article的查询语句添加一个数据表不存在的字段 ISA_N 默认值为 Article

->field('id,...,"不存在的字段值" as 不存在的字段名')

ArticleModel::field('id,title,content,cover_img,"Article" as ISA_N,type,video_width,video_height,video_duration,created_at,updated_at')

并且 notice 表的获取字段数量也要保持一样,添加默认值

->unionAll("select id,title,content,'img','Notice','1','width','height','duration',created_at,updated_at from hq_notice)

字段对应为:

id=>id,title=>title,content=>content,cover_img=>'img',ISA_N=>'Notice',type=>'1',video_width=>'width',video_height=>'height',video_duration=>'duration',created_at=>created_at,updated_at=>updated_at

最后整合的语句如下:

$notice_array = ArticleModel::field('id,title,content,cover_img,"Article" as ISA_N,type,video_width,video_height,video_duration,created_at,updated_at')
            ->where('title|content','LIKE','%'.$search_value.'%')
            ->unionAll("select id,title,content,'img','Notice','1','width','height','duration',created_at,updated_at from hq_notice where CONCAT(title, content) like '%$search_value%'")
            ->limit($start,$end)
            ->order('updated_at','desc')
            ->select()
            ->each(function ($item,$key){
                $item['content'] = filterContent($item['content']);
            });

结果为:
在这里插入图片描述
没有的字段填充的是默认的值

补充:

concat函数

可以使用MySQL的concat函数,将多个字段合并成一个字段进行匹配。以下是示例语句:
SELECT * FROM table_name WHERE CONCAT(column1, column2) LIKE ‘%keyword%’
其中CONCAT函数将column1和column2合并成一个字段进行匹配,%keyword%表示需要匹配的关键字。

相当于使用or操作符
可以使用or操作符来连接多个like子句,让查询同时匹配多个字段。以下是示例语句:
SELECT * FROM table_name WHERE column1 LIKE ‘%keyword%’ OR column2 LIKE ‘%keyword%’
其中table_name为表名,column1和column2是需要匹配的字段名,%keyword%表示需要匹配的关键字。

更多推荐

AI写作宝-为什么要使用写作宝

写作一直是一项需要创造力和思考的任务,人工智能(AI)正逐渐成为我们写作过程中的一位新伙伴。AI写作宝等在线AI写作工具正日益普及,为我们提供了更多的写作选择和可能性。AI写作宝:什么是它们,以及它们能做什么?AI写作宝是一种基于人工智能技术的在线工具,旨在帮助用户生成各种类型的文字内容。它们可以根据用户输入的关键词、

【OS】操作系统课程笔记 第四章 中断和处理机调度

什么是调度?调度就是采用特定算法,安排多个作业或进程运行。4.1中断中断对于操作系统的五个作用:(可能考简答题)实现多道程序设计与并发的基础解决主机与外设的并行工作问题具备控制和管理计算机,提高可靠性实现多机联系实现分时、实时控制等4.1.1中断和指令周期中断响应的三个步骤:终止当前程序执行保存断点信息转到相应的中断处

黑马JVM总结(九)

(1)StringTable_调优1我们知道StringTable底层是一个哈希表,哈希表的性能是跟它的大小相关的,如果哈希表这个桶的个数比较多,元素相对分散,哈希碰撞的几率就会减少,查找的速度较快,反之桶的个数较少,碰撞的几率增高,导致我的链表较长,查找的效率受到影响调优呢主要是调整HashTable桶的个数:时间还

【演讲干货满满】共话数智转型之路:斯歌应邀出席2023德莱维数字技术行业峰会

前不久,2023德莱维数字技术行业峰会在苏州隆重启幕。峰会聚焦“数智转型,融合发展”主题,云集各路大咖,旨在从多元行业、技术维度探索企业数字化发展的革新之道。上海斯歌应邀出席峰会,并于现场进行了《为企业打造更敏捷强壮的“神经网络”》主题演讲,向来自各领域的资深技术专家、行业领袖们分享了BPM领域的前沿洞察与最佳实践,为

Moment.js 处理日期库

文章目录Moment.js是什么Moment.js使用:安装和引入Moment.js:在vue项目中使用Moment.js的基本用法:Moment.js的常用方法示例:总结Moment.js是什么Moment.js是一个轻量级的日期处理库,它提供了一套简单而强大的API,使得在JavaScript中处理日期和时间变得非

通过Power Platform自定义D365 CE 业务需求 - 9. 使用PowerApps自定义

PowerApps提供了许多自定义组件,因此您可以根据业务需求进行自定义。可以为Dynamics365PowerApps开发以下自定义组件:客户端脚本(JavaScript)服务器端代码(插件)服务器端代码(自定义工作流活动)编辑命令栏在Power应用程序中使用客户端JavaScriptMicrosoftDynamic

父域 Cookie实现sso单点登录

单点登录(SingleSignOn,SSO)是指在同一帐号平台下的多个应用系统中,用户只需登录一次,即可访问所有相互信任的应用系统。Cookie的作用域由domain属性和path属性共同决定。在Tomcat中,domain属性默认为当前域的域名/IP地址。path属性的有效值是以“/”开头的路径,在Tomcat中,p

性能测试 —— 性能测试常见的测试指标 !

一、什么是性能测试先看下百度百科对它的定义,性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。我们可以认为性能测试是:通过在测试环境下对系统或构件的性能进行探测,用以验证在生产环境下系统性能是否达到预估的性能需求,发现系统可能存在的性能瓶颈,进而改善优化并系统的性能,提高系

[JAVAee]Spring使用注解来存储与获取Bean对象

前置内容:[JAVAee]Spring项目的创建与基本使用_HY_PIGIE的博客-CSDN博客先前我们在项目中注册类到spring中,要在xml中一行一行的手动添加bean标签.如果对象数目一多起来,就会显得非常繁琐.本文章介绍了使用另一种方法,使用注解的方式快捷的完成Bean对象的存储与获取.配置spring.xm

基于PHP语言研发的抖音矩阵系统源代码开发部署技术文档分享

一、概述本技术文档旨在介绍抖音SEO矩阵系统源代码的开发部署流程,以便开发者能够高效地开发、测试和部署基于PHP语言的开源系统。通过本文档的指引,您将能够掌握抖音SEO矩阵系统的开发环境和部署方案,从而快速地构建出稳定、可靠的短视频SEO优化系统。二、开发环境搭建PHP环境安装:在系统上安装PHP解释器,推荐使用PHP

协议的定义

协议是网络通信实体之间在数据交换过程中需要遵循的规则或约定,是计算机网络有序运行的重要保证。任何一个协议都会显式或隐式地定义3个基本要素:语法、语义和时序,称为协议三要素。语法:语法定义实体之间交换信息的格式与结构,或者定义实体(比如硬件设备)之间传输信号的电平等。语义:定义实体之间交换的信息中需要发送(或包含)哪些控

热文推荐