精华内容
下载资源
问答
  • 高级查询
    千次阅读
    2022-04-24 22:07:05

    MySQL 04 高级查询(二)

    一、学习目标

    1. 掌握IN子查询的用法
    2. 掌握EXISTS子查询
    3. 掌握子查询的使用原则和注意事项
    4. 能够使用SQL进行综合查询

    二、子查询替换表连接

    问题:

    • 查询在“2020-01-02”这天做过“尿常规”这项检查的病人名单

    在这里插入图片描述

    使用多种方法实现查询

    方法一:采用表连接

    • 执行prescription、patient和checkitem三表JOIN操作,再根据条件筛选病人名单

    使用JOIN关键字实现

    SELECT patientName FROM patient pa 
    INNER JOIN prescription pre ON pa.patientID = pre.patientID 
    INNER JOIN checkitem c ON pre.checkItemID = c.checkItemID 
    WHERE c.checkItemName = '尿常规' AND pre.examDate = '2020-01-02';
    

    使用WHERE子句实现

    SELECT patientName FROM patient pa,prescription pre, checkitem c
    WHERE pa.patientID =  pre.patientID AND pre.checkItemID = c.checkItemID 
    AND c.checkItemName = '尿常规' AND pre.examDate = '2020-01-02';
    

    方式二:使用子查询实现复核条件的病人信息筛选

    实现思路:

    1. 查询checkitem表,获得“尿常规”的检查项目编号
    2. 根据检查项目编号,在prescription表中查询在“2020-01-02”这一天做过此检查的病人编号
    3. 根据病人编号在patient表中查找病人姓名
    SELECT patientName FROM patient
    WHERE patientID =
     (SELECT patientID FROM prescription
            WHERE checkItemID = 
                (SELECT checkItemID FROM checkitem
                     WHERE checkItemName = '尿常规')  
    AND examDate = '2020-01-02');
    

    总结分析:

    • 子查询比较灵活、方便,常作为增删改查的筛选条件,适合于操纵一个表的数据
    • 表连接更适合于查看多表的数据

    三、IN子查询

    问题:

    • 如果处理子查询返回多条记录?

    分析:

    • 使用IN子查询

    语法:

    • IN子查询的语法
    SELECT …… FROM 表名 
    WHERE 字段名  IN (子查询);
    

    3.1.子查询返回多个结果示例:
    • 查询在“2020-03-02”做过“血脂、血糖检查”这项检查的病人名单

      SELECT patientName FROM patient WHERE patientID =
          (SELECT patientID FROM prescription WHERE checkItemID = 
              (SELECT checkItemID FROM checkitem 
                      WHERE checkItemName = '血脂、血糖检查')
      AND examDate = '2020-03-02');
      
    • 运行结果

      在这里插入图片描述

    • 解决方法:使用IN子查询
    3.2.IN子查询示例1
    • 常用IN替换等号运算符(=)的子查询

    • IN后面的子查询可以返回多条记录

      #in:限制了病人编号的筛选范围,且其后的子查询可返回多条记录
      SELECT patientName FROM patient WHERE patientID IN
          (SELECT patientID FROM prescription WHERE checkItemID = 
              (SELECT checkItemID FROM checkitem 
               WHERE checkItemName = '血脂、血糖检查')
      AND examDate = '2020-03-02');
      
      3.3.in子查询示例2

    问题:

    • 查询在最近一次开出过“血脂、血糖检查”检查的科室看过病的所有病人姓名、性别、出生日期和住址

    实现思路:

    1. 获得“血脂、血糖检查”这项检查的检查项目编号
    2. 根据获得的检查项目编号查询最近一次得到最近一次检查日期
    3. 根据获得的项目编号和最近一次检查日期,查询科室编号
    4. 根据科室编号查询在这些科室中看过病的所有病人编号
      • 注意:获得的科室编号可能为多条记录
    5. 根据病人编号查询病人的姓名、性别、出生日期和住址
    #1.获得“血脂、血糖检查”这项检查的检查项目编号
    SELECT checkItemID FROM checkitem WHERE checkItemName = '血脂、血糖检查';
    
    #2.根据获得的检查项目编号查询最近一次得到最近一次检查日期
    SELECT MAX(examDate) FROM prescription WHERE checkItemID=(
    SELECT checkItemID FROM checkitem WHERE checkItemName = '血脂、血糖检查');
    
    #3.根据获得的项目编号和最近一次检查日期,查询科室编号
    SELECT depID FROM prescription 
    WHERE examDate=(
    SELECT MAX(examDate) FROM prescription WHERE checkItemID=(
     SELECT checkItemID FROM checkitem WHERE checkItemName = '血脂、血糖检查'))
      AND checkItemID = (
       SELECT checkItemID FROM checkitem WHERE checkItemName = '血脂、血糖检查');
    
      #4.根据科室编号查询在这些科室中看过病的所有病人编号
    SELECT patientID FROM prescription 
    WHERE depID IN (    
     SELECT depID FROM prescription 
       WHERE examDate = (
          SELECT MAX(examDate) FROM prescription 
          WHERE checkItemID = (
            SELECT checkItemID FROM checkitem 
            WHERE checkItemName = '血脂、血糖检查'  
           )  
        )
        AND checkItemID = (
          SELECT checkItemID FROM checkitem 
          WHERE checkItemName = '血脂、血糖检查'
        )
       )
       
    #5.根据病人编号查询病人的姓名、性别、出生日期和住址
    SELECT patientName, gender, birthDate, address FROM patient 
    WHERE patientID IN (
    SELECT patientID FROM prescription 
    WHERE depID IN (    
       SELECT depID FROM prescription 
       WHERE examDate = (
          SELECT MAX(examDate) FROM prescription 
          WHERE checkItemID = (
            SELECT checkItemID FROM checkitem 
            WHERE checkItemName = '血脂、血糖检查'  
           )  
        )
        AND checkItemID = (
          SELECT checkItemID FROM checkitem 
          WHERE checkItemName = '血脂、血糖检查'
        )
       )
       );
    

    四、NOT IN 子查询

    问题:

    • 查询在最近一次开出过“血脂、血糖检查”检查的科室以外其他科室看过病的所有病人姓名、性别、出生日期和住址

      分析:

    实现思路:

    1. 获得“血脂、血糖检查”这项检查的检查项目编号
    2. 根据获得的检查项目编号查询最近一次得到最近一次检查日期
    3. 根据获得的项目编号和最近一次检查日期,查询科室编号
    4. 根据科室编号查询在除这些科室外的其他科室看过病的所有病人编号
    5. 根据病人编号查询病人的姓名、性别、出生日期和住址
    SELECT patientName, gender, birthDate, address FROM patient 
    WHERE patientID IN (
    #4.查询在其他科室看过病的病人编号
    SELECT patientID FROM prescription WHERE depID NOT IN (
       #3.查询科室编号
       SELECT depID FROM prescription WHERE examDate=(
          #2.根据检查项目编号查询得到最近一次检查日期
          SELECT MAX(examDate) FROM prescription 
          WHERE checkItemID=(
            #1.获得“血脂、血糖检查”检查项目编号
            SELECT checkItemID FROM checkitem 
            WHERE checkItemName = '血脂、血糖检查' 
          )
        )
        AND checkItemID = (
          #1.获得“血脂、血糖检查”检查项目编号
          SELECT checkItemID FROM checkitem 
          WHERE checkItemName = '血脂、血糖检查' 
        )
       )
       );
      
    

    五、EXISTS子查询

    问题:

    • 如何用SQL语句检测log表是否已经创建?

      DROP TABLE IF EXISTS log;
      CREATE TABLE IF NOT EXISTS log (
          … … #省略建表语句
      );
      
    • EXISTS关键字是否还有其他用法?

      • EXISTS子查询

    语法:

    SELECT …… FROM 表名 WHERE  EXISTS (子查询);
    
    • 子查询有返回结果: EXISTS子查询结果为TRUE
    • 子查询无返回结果: EXISTS子查询结果为FALSE, 外层查询不执行

    示例:

    需求:

    • 查找是否有病人做过“血脂、血糖检查”
      • 如果有,请显示做过此项检查的病人的姓名、性别、年龄、检查日期和检查结果

    分析:

    • 使用EXISTS子查询查找是否有病人做过“血脂、血糖检查”
      • 如果有病人做过“血脂、血糖检查”,从patient表和prescription表中查询做过此项检查的病人的姓名、性别、年龄、检查日期和检查结果
      • 使用EXISTS子查询可以检测是否存在符合查询条件的记录如果存在,再根据业务逻辑查询符合要求的相应记录
    #查询病人信息和检查信息,病人年龄根据出生日期计算
    SELECT 
    	patientName,
    	gender,
    	FLOOR(DATEDIFF(CURDATE(),birthDate)/365) AS age 
    FROM patient
    #使用EXISTS子句判断是否有做过“血脂、血糖检查”的病人
    WHERE EXISTS(
     SELECT patientID FROM prescription 
     WHERE checkItemID = (
    		SELECT checkItemID FROM checkitem 
    		WHERE checkItemName='血脂、血糖检查') 
     AND patient.patientID = prescription.patientID);
    
    • 和IN子查询一样,EXISTS子查询也允许添加NOT关键字实现相反的操作
      • NOT EXISTS表示结果集中不存在记录是返回true,否则返回false!

    六、NOT EXISTS子查询

    问题:

    • 查询病人“李思雨”是否做过“凝血五项”检查
      • 如果没做过,则插入一条记录
        • 以“内科”的名义在今天给她开一个“凝血五项”的检查

    分析:

    • 可使用NOT EXISTS子查询检测“李思雨”是否做过“凝血五项”检查
      • 如果NOT EXIST子查询的执行结果返回true,则执行数据插入操作
    INSERT INTO prescription(patientID,depID,examDate,checkItemID)
    SELECT patientID, 3 as depID, CURDATE() as examDate, 4 as checkItemID 
    FROM patient 
    WHERE NOT EXISTS (SELECT patientID FROM prescription 
                       WHERE checkItemID = (
    	            SELECT checkItemID FROM checkitem 
    		     WHERE checkItemName='凝血五项') 
    	    AND patient.patientID = prescription.patientID) 
    AND patientName='李思雨';
    

    七、子查询小结

    • 什么是子查询?
      • 当一个查询是另一个查询的条件时,称之为子查询
    • 子查询可以出现在SQL语句的哪些位置?
      • 任何允许使用表达式的地方都可以使用子查询
      • 嵌套在父查询SELECT语句的子查询,可包括
        1. SELECT子句
        2. FROM子句
        3. WHERE子句
        4. GROUP BY子句
        5. HAVING子句

    八、子查询注意事项

    • 通常,将子查询放在比较条件的右边以增加可读性
    • 子查询可以返回单行或多行数据,此时要选择合适的关键字
      • 子查询的返回是单行数据时,比较条件中可以使用比较运算符
      • 子查询的返回是多行数据时,比较条件中需要使用IN或NOT IN关键字
      • 如果判断子查询是否有数据返回时,需要使用EXISTS或NOT EXISTS关键字
    • 只出现在子查询中、而没有出现在父查询中的列不能包含在输出列中

    九、本章总结

    在这里插入图片描述

    更多相关内容
  • 本文针对Linq 高级查询实例进行详解,需要了解的朋友可以参考下
  • ORACLE高级查询ppt

    2019-12-03 14:23:51
    ORALCE高级查询PPT 主要内容包括 表连接 集合操作符 层次查询 GROUP BY扩展 分析函数
  • 实验3-高级查询.pdf

    2020-08-29 15:35:19
    实验三 高级查询 1 实验目的 1 掌握 SQL 的高级查询的使用方法如分组统计嵌套查询集合查询等等 2 实验内容 2.1 掌握 SQL 高级查询使用方法 1 分组统计 2 嵌套查询包括 IN 查询 EXISTS 查询 3 集合查询 3 实验要求 1...
  • 很好的sql高级查询练习题 楼主亲测使用 拒绝大忽悠
  • Python全栈(七)Flask框架之9.ORM排序、分页、高级查询和子查询.pdf
  • 高级查询(SQL)及SQL效率优化[归纳].pdf
  • MySql高级查询

    2018-04-27 09:15:20
    SqlYog高级查询 In子查询 ..................................
  • sql server 高级查询语句小结 讲述sql高级查询语句小结
  • 一个非常实用的代码,仿淘宝高级查询,非常实用
  • 高级查询 数据库高级查询 数据库
  • MySQL高级查询

    万次阅读 多人点赞 2022-01-31 11:29:51
    目录 一、排序 二、分页查询 三、聚合函数 四、分组查询 五、连接查询 1. 内连接查询 2. 左连接查询 3. 右连接查询 4. 自连接查询 六、子查询

    每日分享:

    总有一天,你会明白,能够治愈你的,从来都不是时间,而是你心里的那股释怀和格局。只要内心不慌乱,连世界都影响不了你。

    目录

    一、排序

    二、分页查询

    三、聚合函数

    四、分组查询

    五、连接查询

    1. 内连接查询

    2. 左连接查询

    3. 右连接查询

    4. 自连接查询

    六、子查询


    一、排序

    排序查询语法:

    select * from 表名 order by 列1 asc/desc [,列2 asc/desc,...]

    语法说明:

    1. 先按照列1进行排序,如果列1的值相同时,则按照列2排序
    2. asc:升序排序(从小到大)
    3. desc:降序排序(从大到小)
    4. 默认是升序排序(asc)

    查询未删除男生信息,按学号降序:

    select * from students where is_del = 0 and sex = '男' order by id desc;

    显示所有学生信息,先按年龄从大到小排序,年龄相同时按身高由高到低排序:

    select * from students order by age desc,height desc;

    二、分页查询

    在网上购物时,浏览商品列表的时候,由于数据特别多,一页显示不完,一页一页的进行显示,这就是分页查询

    select * from 表名 limit start,count

    说明:

    1. limit 是分页查询关键字
    2. start 表示开始行索引,默认是0
    3. count 表示查询条数

    查询前三行男生的信息:

    select * from students where sex='男' limit 0,3;

    可以简写为

    select * from students where sex='男' limit 3;

    每页显示m条数据,求第n页显示的数据(关键是求每页的开始行索引)

    select * from students limit (n-1)*m,m;

    三、聚合函数

    聚合函数又叫组函数,通常是对表中的数据进行统计和计算,一般结合分组(group by)来使用,用于统计和计算分组数据

    常用的聚合函数:

    1. count(col):表示求指定列的总行数
    2. max(col):表示求指定列的最大值
    3. min(col):表示求指定列的最小值
    4. sum(col):表示求指定列的和
    5. avg(col):表示指定列的平均值

    求总行数:

    返回非null数据的总行数

    select count(height) from students;

    返回总行数,包含null值记录

    select count(*) from students;

     

    求最大值:

    查询男生编号的最大值

    select max(id) from students where sex='男';

    求最小值:

    查询未删除的学生最小编号

    select min(id) from students where is_del=0;

    求和:

    查询男生的总身高

    select sum(height) from students where sex='男';

    查询男生的平均身高

    select sum(height) / count(*) from students where sex='男';

    求平均值:

    求男生的平均身高,聚合函数不统计null值

    select avg(height) from students where sex='男';

    求男生的平均身高,包含身高为null的值

    select avg(ifnull(height,0)) from students where sex='男';

    说明:

    • ifnull函数:表示判断指定字段的值是否为null,如果为空则使用自己提供的值

    聚合函数特点:

    • 聚合函数默认忽略字段为null的记录,要想列值为null的记录也参与计算,必须使用ifnull函数对null值做替换

    四、分组查询

    分组查询就是将查询结果按照指定字段进行分组,字段中数据相等的分为一组

    分组查询基本的语法格式:

    group by 列名 [having 条件表达式] [with rollup]

    说明:

    • 列名:是指按照指定字段的值进行分组
    • having 条件表达式:用来过滤分组后的数据
    • with rollup:在所有记录的最后加上一条记录,显示select查询时聚合函数的统计和计算结果

    group by 的使用:

    group by可用于单个字段分组,也可用于多个字段分组

    根据sex字段来分组

    select gender from students group by sex;

    根据name和sex字段来分组

    select name,sex from students group by name,sex;

    group by + group_concat()的使用:

    group_concat(字段名):统计每个分组指定字段的信息集合,每个信息之间用逗号分割

    根据sex字段进行分组,查询sex字段和分组的name字段信息

    select sex,group_concat(name) from students group by sex;

    group by + 聚合函数的使用:

    统计不同性别的人的平均年龄

    select sex,avg(age) from students group by sex;

    统计不同性别的人的个数

    select sex,count(*) from students group by sex;

    group by + having的使用:

    having作用和where类似都是过滤数据的,但having是过滤分组数据的,只能用于group by

    根据sex字段进行分组,统计分组条数大于2的

    select sex,count(*) from students group by sex having count(*)>2;

    group by + with rollup的使用:

    with rollup的作用是:在最后记录后面新增一行,显示select查询时聚合函数的统计和计算结果

    根据sex字段进行分组,汇总总人数

    select sex,count(*) from students group by sex with rollup;

    根据sex字段进行分组,汇总所有人年龄

    select sex,group_concat(age) from students group by sex with rollup;

    小结:

    • group by 根据指定的一个或者多个字段对数据进行分组
    • group_concat(字段名)函数是统计每个分组指定字段的信息集合
    • 聚合函数在和group by 结合使用时,聚合函数统计和计算的是每个分组的数据
    • having 是对分组数据进行条件过滤
    • with rollup 在最后记录后面新增一行,显示select查询时聚合函数的统计和计算结果

    五、连接查询

    连接查询可以实现多个表的查询,当查询的字段数据来自不同的表就可以使用连接查询来完成

    连接查询分为:

    1. 内连接查询
    2. 左连接查询
    3. 右连接查询
    4. 自连接查询

    1. 内连接查询

    查询两个表中符合条件的共有记录(取交集)

    内连接查询语法格式:

    select 字段 from 表1 inner join 表2 on 表1.字段1 = 表2.字段2

    说明:

    • inner join 就是内连接查询关键字
    • on 就是连接查询条件

    使用内连接查询学生表与班级表:

    select * from students s inner join classes c on s.c_id = c.id;

    原本两个表的内容:

    使用内连接:

    2. 左连接查询

    以左表为主根据条件查询右表数据,如果根据条件查询右表数据不存在则使用null值填充

    左连接查询语法格式:

    select 字段 from 表1 left join 表2 on 表1.字段1 = 表2.字段2

    说明:

    • left join 就是左连接查询关键字
    • on 就是连接查询条件
    • 表1 是左表
    • 表2 是右表

    使用左连接查询学生表与班级表:

    select * from students s left join classes c on s.c_id = c.id;

    3. 右连接查询

    以右表为主根据条件查询左表数据,如果根据条件查询左表数据不存在则使用null值填充

    右连接查询语法格式:

    select 字段 from 表1 right join 表2 on 表1.字段1 = 表2.字段2;

    说明:

    • right join 就是右连接查询关键字
    • on 就是连接查询条件
    • 表1 是左表
    • 表2 是右表

    使用右连接查询学生表与班级表:

    select * from students s right join classes c on s.c_id = c.id;

    4. 自连接查询

    左表和右表是同一个表,根据连接查询条件查询两个表中的数据

    创建areas表:

    create table areas(

    id varchar(20) not null primary key,

    title varchar(30) not null,

    pid varchar(20)

    );

    执行sql文件给areas表导入数据:

    source areas.sql;

    sql文件内容:

    insert into areas values('11000', '北京市', null);
    insert into areas values('11001', '北京市', '11000');
    insert into areas values('11002', '东城区', '11001');
    insert into areas values('11003', '西城区', '11001');
    insert into areas values('11004', '朝阳区', '11001');
    insert into areas values('11005', '丰台区', '11001');
    insert into areas values('11006', '海淀区', '11001');
    insert into areas values('12000', '河北省', null);
    insert into areas values('12001', '石家庄市', '12000');
    insert into areas values('12002', '长安区', '12001');
    insert into areas values('12003', '桥东区', '12001');
    insert into areas values('12004', '桥西区', '12001');
    insert into areas values('12005', '新华区', '12001');

    说明:

    • source 表示执行的sql文件

    自连接查询的用法:

    select c.id, c.title, c.pid, p.title from areas c inner join areas p on c.pid = p.id;

    说明:

    • 自连接查询必须对表起别名

    六、子查询

    在一个select语句中,嵌入了另外一个select语句,那么被嵌入的select语句称之为子查询语句,外部的那个select语句则称为主查询

    主查询和子查询的关系:

    1. 子查询是嵌入到主查询中
    2. 子查询是辅助主查询的,要么充当条件,要么充当数据源
    3. 子查询是可以独立存在的语句,是一条完整的select语句

    查询大于平均年龄的学生:

    select * from students where age > (select avg(age) from students);

    查询学生在班的所有班级名字:

    select name from classes where id in (select c_id from students where c_id is not null);

    查找年龄最大,身高最高的学生:

    select * from students where age=(select max(age) from students) and height=(select max(height) from students);

    可以简写为:

    select * from students where (age,height) = (select max(age), max(height) from students);

    展开全文
  • 高级查询支持库

    2020-07-24 11:02:19
    高级查询支持库
  • 用于高级用户所使用的api知识查询的CHM文件,本文件可以查询几百种API调用,欢迎使用!!!
  • 自定义高级查询Extjs

    2015-07-03 08:23:10
    自定义高级查询Extjs
  • 【Spring Data ElasticSearch】高级查询,聚合1. 高级查询1.1 基本查询1.2 自定义查询1.3 分页查询1.4 排序2. 聚合2.1 聚合为桶2.2 嵌套聚合,求平均值 1. 高级查询 1.1 基本查询 package com.siyi.elasticsearch; ...

    1. 高级查询

    1.1 基本查询

    package com.siyi.elasticsearch;
    
    import com.siyi.elasticsearch.pojo.Item;
    import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
    
    import java.util.List;
    
    public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
    
    }
    
    @Test
    public void testQuery(){
        // 词条查询
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "小米");
        // 执行查询
        Iterable<Item> items = this.itemRepository.search(queryBuilder);
        items.forEach(System.out::println);
    }
    

    Repository的search方法需要QueryBuilder参数,elasticSearch为我们提供了一个对象QueryBuilders:
    在这里插入图片描述

    QueryBuilders提供了大量的静态方法,用于生成各种不同类型的查询对象,例如:词条、模糊、通配符等QueryBuilder对象。

    lasticsearch提供很多可用的查询方式,但是不够灵活。如果想玩过滤或者聚合查询等就很难了。
    所以我们需要自定义查询。

    1.2 自定义查询

    	@Test
    	public void testNativeQuery(){
    	    // 构建查询条件
    	    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    	    // 添加基本的分词查询
    	    queryBuilder.withQuery(QueryBuilders.matchQuery("title", "小米"));
    	    // 执行搜索,获取结果
    	    Page<Item> items = this.itemRepository.search(queryBuilder.build());
    	    // 打印总条数
    	    System.out.println(items.getTotalElements());
    	    // 打印总页数
    	    System.out.println(items.getTotalPages());
    	    items.forEach(System.out::println);
    	}
    

    NativeSearchQueryBuilder:Spring提供的一个查询条件构建器,帮助构建json格式的请求体

    Page<item>:默认是分页查询,因此返回的是一个分页的结果对象,包含属性:

    • totalElements:总条数
    • totalPages:总页数
    • Iterator:迭代器,本身实现了Iterator接口,因此可直接迭代得到当前页的数据
    • 其它属性:

    1.3 分页查询

    利用NativeSearchQueryBuilder可以方便的实现分页:

    @Test
    public void testNativeQuery(){
        // 构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 添加基本的分词查询
        queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));
    
        // 初始化分页参数
        int page = 0;
        int size = 3;
        // 设置分页参数
        queryBuilder.withPageable(PageRequest.of(page, size));
    
        // 执行搜索,获取结果
        Page<Item> items = this.itemRepository.search(queryBuilder.build());
        // 打印总条数
        System.out.println(items.getTotalElements());
        // 打印总页数
        System.out.println(items.getTotalPages());
        // 每页大小
        System.out.println(items.getSize());
        // 当前页
        System.out.println(items.getNumber());
        items.forEach(System.out::println);
    }
    

    注意:elasticsearch分页是从0开始的。

    1.4 排序

    排序也通用通过NativeSearchQueryBuilder完成:

    @Test
    public void testSort(){
        // 构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 添加基本的分词查询
        queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));
    
        // 排序
        queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));
    
        // 执行搜索,获取结果
        Page<Item> items = this.itemRepository.search(queryBuilder.build());
        // 打印总条数
        System.out.println(items.getTotalElements());
        items.forEach(System.out::println);
    }
    

    2. 聚合

    2.1 聚合为桶

    桶就是分组,比如这里我们按照品牌brand进行分组:

    @Test
    public void testAgg(){
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 不查询任何结果
        queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));
        // 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand
        queryBuilder.addAggregation(
            AggregationBuilders.terms("brands").field("brand"));
        // 2、查询,需要把结果强转为AggregatedPage类型
        AggregatedPage<Item> aggPage = (AggregatedPage<Item>) this.itemRepository.search(queryBuilder.build());
        // 3、解析
        // 3.1、从结果中取出名为brands的那个聚合,
        // 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型
        StringTerms agg = (StringTerms) aggPage.getAggregation("brands");
        // 3.2、获取桶
        List<StringTerms.Bucket> buckets = agg.getBuckets();
        // 3.3、遍历
        for (StringTerms.Bucket bucket : buckets) {
            // 3.4、获取桶中的key,即品牌名称
            System.out.println(bucket.getKeyAsString());
            // 3.5、获取桶中的文档数量
            System.out.println(bucket.getDocCount());
        }
    }
    

    关键API:

    • AggregationBuilders:聚合的构建工厂类。所有聚合都由这个类来构建,看看他的静态方法:

      • AggregatedPage:聚合查询的结果类。它是Page<T>的子接口:
        在这里插入图片描述

      AggregatedPagePage功能的基础上,拓展了与聚合相关的功能,它其实就是对聚合结果的一种封装,大家可以对照聚合结果的JSON结构来看。

      而返回的结果都是Aggregation类型对象,不过根据字段类型不同,又有不同的子类表示

      我们看下页面的查询的JSON结果与Java类的对照关系:

    2.2 嵌套聚合,求平均值

    @Test
    public void testSubAgg(){
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 不查询任何结果
        queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));
        // 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand
        queryBuilder.addAggregation(
            AggregationBuilders.terms("brands").field("brand")
            .subAggregation(AggregationBuilders.avg("priceAvg").field("price")) // 在品牌聚合桶内进行嵌套聚合,求平均值
        );
        // 2、查询,需要把结果强转为AggregatedPage类型
        AggregatedPage<Item> aggPage = (AggregatedPage<Item>) this.itemRepository.search(queryBuilder.build());
        // 3、解析
        // 3.1、从结果中取出名为brands的那个聚合,
        // 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型
        StringTerms agg = (StringTerms) aggPage.getAggregation("brands");
        // 3.2、获取桶
        List<StringTerms.Bucket> buckets = agg.getBuckets();
        // 3.3、遍历
        for (StringTerms.Bucket bucket : buckets) {
            // 3.4、获取桶中的key,即品牌名称  3.5、获取桶中的文档数量
            System.out.println(bucket.getKeyAsString() + ",共" + bucket.getDocCount() + "台");
    
            // 3.6.获取子聚合结果:
            InternalAvg avg = (InternalAvg) bucket.getAggregations().asMap().get("priceAvg");
            System.out.println("平均售价:" + avg.getValue());
        }
    }
    

    展开全文
  • 实验3-高级查询.doc

    2020-09-07 06:47:52
    实验三 高级查询 实验目的 掌握SQL的高级查询的使用方法如分组统计嵌套查询集合查询等等 实验内容 掌握SQL高级查询使用方法 分组统计 嵌套查询包括IN查询EXISTS查询 集合查询 实验要求 深入复习教材第三章SQL有关...
  • Mysql数据库的高级查询_多表查询
  • WinForm高级查询窗体

    2015-05-28 11:57:26
    制作WinForm通用的高级查询窗体,可直接调用。内附调用方法、字符串拼接例子。 (项目可以直接添加该窗体。添加时,三个文件同时添加即可。)
  • ORACLE高级技巧高级查询[借鉴].pdf
  • sql高级查询

    2012-10-22 08:36:43
    sql高级查询
  • 子查询与高级查询PPT学习教案.pptx
  • Oracle数据库应用教程子查询与高级查询.pptx
  • SQL高级查询案例定义.pdf
  • 易语言学习-高级查询条件支持库.zip
  • Oracle数据库应用教程--子查询与高级查询.pptx
  • sql高级查询50题.docx

    2021-10-10 22:15:58
    sql高级查询50题.docx

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 389,058
精华内容 155,623
关键字:

高级查询