复杂 SQL 实现分组分情况分页查询

简介: 在处理数据库查询时,分页是一个常见的需求。尤其是在处理大量数据时,一次性返回所有结果可能会导致性能问题。因此,我们需要使用分页查询来限制返回的结果数量。同时,根据特定的条件筛选数据也是非常常见的需求。在本博客中,我们将探讨如何根据 camp_status 字段分为 6 种情况进行分页查询,并根据 camp_type 字段区分活动类型,返回不同的字段。我们将使用 SQL 变量来实现这一功能,并通过示例进行详细解释。

 其他系列文章导航

Java基础合集

数据结构与算法合集

设计模式合集

多线程合集

分布式合集

ES合集


文章目录

其他系列文章导航

文章目录

前言

一、根据 camp_status 字段分为 6 种情况

1.1 SQL语句

1.2 SQL解释

二、分页 SQL 实现

2.1 SQL语句

2.2 根据 camp_type 区分返回字段

2.3 根据 camp_status 字段分为 6 种情况

三、分页实现

四、总结


前言

在处理数据库查询时,分页是一个常见的需求。

尤其是在处理大量数据时,一次性返回所有结果可能会导致性能问题。

因此,我们需要使用分页查询来限制返回的结果数量。同时,根据特定的条件筛选数据也是非常常见的需求。

在本博客中,我们将探讨如何根据 camp_status 字段分为 6 种情况进行分页查询,并根据  camp_type 字段区分活动类型,返回不同的字段。

我们将使用 SQL 变量来实现这一功能,并通过示例进行详细解释。


一、根据 camp_status 字段分为 6 种情况

1.1 SQL语句

要将分页结果按 6 种情况来区分。

SQL如下:

SELECT         count(*)                                                                 AS allCampCount,
               SUM(CASE WHEN CAMP_STATUS IN ('31', '32', '35', '55') THEN 1 ELSE 0 END) AS approvalCampCount,
               SUM(CASE WHEN CAMP_STATUS IN ('40', '41', '56') THEN 1 ELSE 0 END)       AS toExecuteCampCount,
               SUM(CASE WHEN CAMP_STATUS IN ('42', '66', '67') THEN 1 ELSE 0 END)       AS executeCampCount,
               SUM(CASE WHEN CAMP_STATUS IN ('50', '60') THEN 1 ELSE 0 END)             AS completeCampCount,
               SUM(CASE WHEN CAMP_STATUS IN ('30') THEN 1 ELSE 0 END)                   AS overruleCampCount
        FROM BMA_MARKET_CAMP
        WHERE USER_ID = #{userId}

image.gif

1.2 SQL解释

这是一个SQL查询,用于从名为BMA_MARKET_CAMP的表中选择和计算数据。下面是对这个查询的逐行解释:

    1. SELECT count(*) AS allCampCount: 这一行计算了BMA_MARKET_CAMP表中的总记录数,并将这个数量命名为allCampCount
    2. SUM(CASE WHEN CAMP_STATUS IN ('31', '32', '35', '55') THEN 1 ELSE 0 END) AS approvalCampCount: 这一行计算了CAMP_STATUS字段值为'31', '32', '35', 或 '55'的总数,并将这个数量命名为approvalCampCount。这些状态可能是表示“待批准”或“正在批准”的状态代码。
    3. SUM(CASE WHEN CAMP_STATUS IN ('40', '41', '56') THEN 1 ELSE 0 END) AS toExecuteCampCount: 这一行计算了CAMP_STATUS字段值为'40', '41', 或 '56'的总数,并将这个数量命名为toExecuteCampCount。这些状态可能是表示“待执行”或“即将执行”的状态代码。
    4. SUM(CASE WHEN CAMP_STATUS IN ('42', '66', '67') THEN 1 ELSE 0 END) AS executeCampCount: 这一行计算了CAMP_STATUS字段值为'42', '66', 或 '67'的总数,并将这个数量命名为executeCampCount。这些状态可能是表示“正在执行”或“已执行”的状态代码。
    5. SUM(CASE WHEN CAMP_STATUS IN ('50', '60') THEN 1 ELSE 0 END) AS completeCampCount: 这一行计算了CAMP_STATUS字段值为'50'或'60'的总数,并将这个数量命名为completeCampCount。这些状态可能是表示“已完成”或“完全完成”的状态代码。
    6. SUM(CASE WHEN CAMP_STATUS IN ('30') THEN 1 ELSE 0 END) AS overruleCampCount: 这一行计算了CAMP_STATUS字段值为'30'的总数,并将这个数量命名为overruleCampCount。这个状态可能是表示“已否决”或“推翻”的状态代码。
    7. FROM BMA_MARKET_CAMP WHERE USER_ID = #{userId}: 最后,指定了数据来源的表是BMA_MARKET_CAMP,并且只选择那些USER_ID字段等于给定参数#{userId}的记录。

    总的来说,这个查询是为了获取与特定用户相关的各种 camp 状态的数量。


    二、分页 SQL 实现

    2.1 SQL语句

    这是整个 SQL 语句,下面会细细讲解!

    SQL如下:

    SELECT TOUCH_TYPE,
                   t1.CAMP_TYPE,
                   NAME,
                   SMS_CONTENT,
                   CASE
                       WHEN t1.CAMP_TYPE = '0' THEN
                           NULL
                       ELSE
                           START_DATE END AS START_DATE,
                   CASE
                       WHEN t1.CAMP_TYPE = '0' THEN
                           EXE_START_TIME
                       ELSE
                           START_TIME END AS START_TIME,
                   CASE
                       WHEN t1.CAMP_TYPE = '0' THEN
                           NULL
                       ELSE
                           END_DATE END   AS END_DATE,
                   CASE
                       WHEN t1.CAMP_TYPE = '0' THEN
                           NULL
                       ELSE
                           END_TIME END   AS END_TIME
            FROM CAMP t1
                     left join CAMP_INFO t2 on t1.ID = t2.CAMP_ID
            WHERE CAMP_STATUS  in
            <foreach close=")" collection="campStatus" item="campStatus" open="(" separator=", ">
                #{campStatus,jdbcType=VARCHAR}
            </foreach>
              AND USER_ID = #{userId}

    image.gif

    2.2 根据 camp_type 区分返回字段

      • 当活动类型为 0 时,只需要返回 EXE_STRAR_TIME 字段。
      • 其他的活动类型要返回 START_DATE , START_TIME , END_DATE , END_TIME 四个字段。

      SQL部分如下:

      CASE
                         WHEN t1.CAMP_TYPE = '0' THEN
                             NULL
                         ELSE
                             START_DATE END AS START_DATE,
                     CASE
                         WHEN t1.CAMP_TYPE = '0' THEN
                             EXE_START_TIME
                         ELSE
                             START_TIME END AS START_TIME,
                     CASE
                         WHEN t1.CAMP_TYPE = '0' THEN
                             NULL
                         ELSE
                             END_DATE END   AS END_DATE,
                     CASE
                         WHEN t1.CAMP_TYPE = '0' THEN
                             NULL
                         ELSE
                             END_TIME END   AS END_TIME

      image.gif

      2.3 根据 camp_status 字段分为 6 种情况

      解释如下:

        1. WHERE CAMP_STATUS in: 这表示我们要在SQL查询中添加一个条件,即CAMP_STATUS的值必须在给定的列表中。
        2. <foreach ...>: 这是MyBatis的循环语句,用于遍历集合或数组,并动态生成SQL的部分内容。
        3. collection="campStatus": 这表示我们要遍历的集合或数组的名称是campStatus
        4. item="campStatus": 在每次循环中,当前的元素值会被赋值给名为campStatus的变量。
        5. open="("close=")": 这些指示MyBatis在循环开始前添加一个左括号(,并在循环结束后添加一个右括号)
        6. separator=", ">: 这表示在每次循环后,我们添加一个逗号,`和一个空格。
        7. #{campStatus,jdbcType=VARCHAR}: 这是MyBatis的参数占位符。它表示我们要将当前循环中的campStatus变量的值插入到SQL查询中。jdbcType=VARCHAR指定了参数的类型,这里假设它是VARCHAR类型。

        综上所述,这个片段的作用是动态生成一个SQL查询的条件,该条件检查CAMP_STATUS是否在给定的campStatus列表中。

        SQL部分如下:

        SELECT 
                    ...
                FROM 
                    ...
                WHERE CAMP_STATUS  in
                <foreach close=")" collection="campStatus" item="campStatus" open="(" separator=", ">
                    #{campStatus,jdbcType=VARCHAR}
                </foreach>
                ...

        image.gif

        这里传入的是一个 list,这样传入即可:

        image.gif编辑

        定义一个请求类:

        @Data
        public class CampDataInfoInIndexRequest {
            List<Integer> campStatusList;
            private int pageNum;
            private int pageSize;
        }

        image.gif


        三、分页实现

        实现一个 PageUtils 。

        代码如下:

        public class PageUtils {
            /**
             * 泛型方法 进行结果的分页
             * 当pageNum*pageSize>result.size那么就取result的最后一页数据
             * 否则就取相应页的数据
             *
             * @param result
             * @param pageNum
             * @param pageSize
             * @return
             */
            public static <T> List<T> pageResult(List<T> result, Integer pageNum, Integer pageSize) {
                if (Objects.isNull(result) || result.size() == 0) {
                    return result;
                }
                int maxSize = result.size();
                if (maxSize < pageNum * pageSize + pageSize) {
                    int maxPage = maxSize / pageSize;
                    return result.subList(maxPage * pageSize, result.size());
                }
                return result.subList(pageNum * pageSize, (pageNum + 1) * pageSize);
            }
        }

        image.gif

        再通过一个 PageResultVO 返回即可。

        代码如下:

        @Data
        public class PageResultVO {
            private Integer total;
            private List<?> list;
        }
        //ServiceImpl层
        List<CampInfoVO> infoList = PageUtils.pageResult(info, pageNum, pageSize);
        PageResultVO pageResultVO = new PageResultVO();
        pageResultVO.setTotal(info.size());
        pageResultVO.setList(infoList);

        image.gif


        四、总结

        在这篇博客中,我们探讨了如何使用SQL实现分页查询,并根据camp_status和camp_type字段进行筛选。

        通过使用变量和适当的SQL语法,我们可以根据特定的条件动态地构建查询,从而返回满足我们需求的结果。

        通过这种方式,我们可以灵活地构建和执行查询,以满足不同的需求。这对于处理大量数据和实现复杂的筛选条件非常有用。

        希望这篇博客能帮助你更好地理解和应用SQL分页查询和筛选功能!

        目录
        相关文章
        |
        6天前
        |
        SQL 数据库
        三、SQL的基础查询
        三、SQL的基础查询
        29 0
        |
        5月前
        |
        关系型数据库 MySQL 数据库
        Mysql数据库 6.SQL语言 分组、分页查询
        Mysql数据库 6.SQL语言 分组、分页查询
        60 2
        |
        7月前
        |
        SQL 关系型数据库 MySQL
        SQL分页查询详解
        分页查询是在数据库中检索数据的一种常见需求。它允许我们从大型数据集中获取有限数量的数据,以便于显示在应用程序的用户界面上。在本文中,我们将详细介绍SQL中的分页查询,包括基本语法、常见应用场景以及如何在不同数据库管理系统中执行分页查询。
        399 1
        |
        7月前
        |
        SQL 数据库
        使用 SQL 进行排序查询
        在数据库中,我们经常需要对查询的结果进行排序,以便更容易地理解和分析数据。SQL(Structured Query Language)提供了强大的排序功能,允许我们按照指定的列对数据进行升序或降序排序。本文将详细介绍如何使用 SQL 进行排序查询,包括基本的排序语法、多列排序、自定义排序顺序等内容。
        216 0
        基础查询 SQL3查询结果去重&&SQL4查询结果限制返回行数&&SQL5将查询后的列重新命名
        基础查询 SQL3查询结果去重&&SQL4查询结果限制返回行数&&SQL5将查询后的列重新命名
        152 0
        基础查询 SQL3查询结果去重&&SQL4查询结果限制返回行数&&SQL5将查询后的列重新命名
        |
        SQL 关系型数据库 MySQL
        Mysql常用sql语句(6)- limit 限制查询结果的条数
        Mysql常用sql语句(6)- limit 限制查询结果的条数
        1385 0
        Mysql常用sql语句(6)- limit 限制查询结果的条数
        |
        SQL
        sql 分页
        1.分页方案一:(利用Not In和SELECT TOP分页)效率次之 语句形式: SELECT TOP 10 * FROM TestTable WHERE(ID NOT IN (SELECT TOP 20  id FROM  TestTable  ORDERBY  id))   ORDERBYID...
        830 0
        |
        SQL 安全 存储
        |
        SQL 关系型数据库 Oracle