复杂 SQL 实现分组分情况分页查询
2023-12-20 18:48:42
其他系列文章导航
文章目录
前言
在处理数据库查询时,分页是一个常见的需求。
尤其是在处理大量数据时,一次性返回所有结果可能会导致性能问题。
因此,我们需要使用分页查询来限制返回的结果数量。同时,根据特定的条件筛选数据也是非常常见的需求。
在本博客中,我们将探讨如何根据 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}
1.2 SQL解释
这是一个SQL查询,用于从名为BMA_MARKET_CAMP
的表中选择和计算数据。下面是对这个查询的逐行解释:
SELECT count(*) AS allCampCount
: 这一行计算了BMA_MARKET_CAMP
表中的总记录数,并将这个数量命名为allCampCount
。SUM(CASE WHEN CAMP_STATUS IN ('31', '32', '35', '55') THEN 1 ELSE 0 END) AS approvalCampCount
: 这一行计算了CAMP_STATUS
字段值为'31', '32', '35', 或 '55'的总数,并将这个数量命名为approvalCampCount
。这些状态可能是表示“待批准”或“正在批准”的状态代码。SUM(CASE WHEN CAMP_STATUS IN ('40', '41', '56') THEN 1 ELSE 0 END) AS toExecuteCampCount
: 这一行计算了CAMP_STATUS
字段值为'40', '41', 或 '56'的总数,并将这个数量命名为toExecuteCampCount
。这些状态可能是表示“待执行”或“即将执行”的状态代码。SUM(CASE WHEN CAMP_STATUS IN ('42', '66', '67') THEN 1 ELSE 0 END) AS executeCampCount
: 这一行计算了CAMP_STATUS
字段值为'42', '66', 或 '67'的总数,并将这个数量命名为executeCampCount
。这些状态可能是表示“正在执行”或“已执行”的状态代码。SUM(CASE WHEN CAMP_STATUS IN ('50', '60') THEN 1 ELSE 0 END) AS completeCampCount
: 这一行计算了CAMP_STATUS
字段值为'50'或'60'的总数,并将这个数量命名为completeCampCount
。这些状态可能是表示“已完成”或“完全完成”的状态代码。SUM(CASE WHEN CAMP_STATUS IN ('30') THEN 1 ELSE 0 END) AS overruleCampCount
: 这一行计算了CAMP_STATUS
字段值为'30'的总数,并将这个数量命名为overruleCampCount
。这个状态可能是表示“已否决”或“推翻”的状态代码。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}
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
2.3?根据 camp_status 字段分为 6 种情况
解释如下:
WHERE CAMP_STATUS in
: 这表示我们要在SQL查询中添加一个条件,即CAMP_STATUS
的值必须在给定的列表中。<foreach ...>
: 这是MyBatis的循环语句,用于遍历集合或数组,并动态生成SQL的部分内容。collection="campStatus"
: 这表示我们要遍历的集合或数组的名称是campStatus
。item="campStatus"
: 在每次循环中,当前的元素值会被赋值给名为campStatus
的变量。open="("
?和?close=")"
: 这些指示MyBatis在循环开始前添加一个左括号(
,并在循环结束后添加一个右括号)
。separator=", ">: 这表示在每次循环后,我们添加一个逗号
,`和一个空格。#{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>
...
这里传入的是一个 list,这样传入即可:
定义一个请求类:
@Data
public class CampDataInfoInIndexRequest {
List<Integer> campStatusList;
private int pageNum;
private int pageSize;
}
三、分页实现
实现一个?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);
}
}
再通过一个?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);
四、总结
在这篇博客中,我们探讨了如何使用SQL实现分页查询,并根据camp_status和camp_type字段进行筛选。
通过使用变量和适当的SQL语法,我们可以根据特定的条件动态地构建查询,从而返回满足我们需求的结果。
通过这种方式,我们可以灵活地构建和执行查询,以满足不同的需求。这对于处理大量数据和实现复杂的筛选条件非常有用。
希望这篇博客能帮助你更好地理解和应用SQL分页查询和筛选功能!
文章来源:https://blog.csdn.net/kologin/article/details/135108661
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!