【SQL编程】记录一次不了解Greenplum数据库编号函数使用方法导致的问题(1次疏忽 + 1次不必要 = 2次弯路)

177 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1. 问题描述

有这么一个需求,查询出来的数据需要显示相对的排序编号,还要进行分页操作,我首先想到的就是 ROW_NUMBER 函数,MySQL、Oracle 都有类似的编号函数,走起 :smile:

SELECT 
ROW_NUMBER ( ) OVER ( ) AS "rowNum",
	recommend_field AS "recommendField",
	recommend_value AS "recommendValue",
	sort_tag AS "sortTag" 
FROM
	data_recommend_car 
WHERE
	recommend_field = 'imsi' 
ORDER BY
	sort_tag DESC
	LIMIT 5 OFFSET 0

在这里插入图片描述 这结果显然不是想要,看到结果也恍然大悟,SQL的执行顺序是FROM > WHERE > SELECT > ORDER BY > LIMIT SELECT 阶段编号已经被安排了,重新排序后编号是不会再变动的。

2. 走向弯路

:one: 次弯路:既然先产生编号后排序,那就先用子查询进行排序,然后再添加编号。

SELECT ROW_NUMBER
	( ) OVER ( ) AS "rowNum",
	T.* 
FROM
	( SELECT 
	recommend_field AS "recommendField", 
	recommend_value AS "recommendValue", 
	sort_tag AS "sortTag" 
	FROM data_recommend_car 
	WHERE recommend_field = 'imsi'
	ORDER BY sort_tag DESC 
	) T 
	LIMIT 5 OFFSET 0

想法很美好,结果又找不到:

在这里插入图片描述 在这里插入图片描述 发现仅运行子查询是排序好的,再次从 T 表查询数据时,顺序又被打乱了 :cry:

:one: 次不必要:既然数据库排不了序,那就后台代码实现吧 :smiley:

        // 添加行号
        for (int i = 0, size = res.size(); i < size; i++) {
        	// 计算行号
            int rowNum = (curPage - 1) * pageSize + i + 1;
            // 赋值
            res.get(i).setRowNum((long) rowNum);
        }

3. 名门正派

不会吧!不会吧!数据库连排序都搞不出来?还真的不会,不是数据库不会,是自己不会用!!!修改后的SQL添加排序 ORDER BY sort_tag DESC

SELECT 
ROW_NUMBER ( ) OVER ( ORDER BY sort_tag DESC ) AS "rowNum",
	recommend_field AS "recommendField",
	recommend_value AS "recommendValue",
	sort_tag AS "sortTag" 
FROM
	data_recommend_car 
WHERE
	recommend_field = 'imsi' 
	LIMIT 5 OFFSET 0

在这里插入图片描述 实现了排序的需求,编号函数还有 rand ( ) over ( ) 等,小伙伴儿们可以自行搜索使用。