我们在上一篇文章中介绍了怎么用 SQL 打印 5 x 5 的矩阵,今天的内容仍旧围绕这个主题,只不过规则稍有点不同。
先来看看要实现的效果。
和前面一篇文章中的表格不同之处在于:偶数行的排序不再是从左到右是递增的,而是递减,或者说是从右到左递增。
完整的规则:
- 有一张 5 x 5 的表格,我们要往这张表格中填充 1~25 的数字;
- 如果是奇数行,则从左到右填充数字;如果是偶数行,就需要按从右到左的顺序填入数字。
- 先从表格的左上角(即第一行第一列)填入数字 “1”,在第一行第二列填入“2”,直到把第一行填满;
- 当上一行填满的时候,就开始往下一行填数据。比如,第二行要从右往左依次填入“6”、“7”、“8”、“9”、“10”。
- 循环反复,直到所有空格都填满数字。
接下来,我们将实现这个需求。
第一步,生成 1~25 的数。
WITH recursive t_seq (num) AS
(SELECT
1 AS num
UNION ALL
SELECT
num + 1 AS num
FROM
t_seq
WHERE num < 25)
SELECT * FROM t_seq
第二步,生成每个数对应的组号/行号。
x0 AS
(SELECT
num,
CEIL(num / 5) AS group_no
FROM
t_seq)
SELECT * FROM x0
第三步,动态排序。
若是奇数行,则组内默认按升序排序,反之,则是降序排序。
使用 IF(是偶数行, - 1 * 原排序字段, 原排序字段) AS 新排序字段
可以达到依据条件实现动态排序的效果。
x1 AS
(SELECT
*,
IF(group_no % 2 = 0, - 1 * num, num) AS ordered,
row_number () over () AS seq
FROM
x0
ORDER BY group_no,
ordered)
SELECT * FROM x1
注意,我们在 SQL 中加入了一个新字段 seq,seq 存储的是 1~25 的自然数,它将作为后面步骤的行转列的依据。
执行上面的 SQL ,部分结果如下。
num group_no ordered seq
------ -------- ------- --------
1 1 1 1
2 1 2 2
3 1 3 3
4 1 4 4
5 1 5 5
10 2 -10 6
9 2 -9 7
8 2 -8 8
7 2 -7 9
6 2 -6 10
第四步,行转列。
x2 AS
(SELECT
group_no AS row_no,
MAX(IF(seq % 5 = 1, num, NULL)) AS A,
MAX(IF(seq % 5 = 2, num, NULL)) AS B,
MAX(IF(seq % 5 = 3, num, NULL)) AS C,
MAX(IF(seq % 5 = 4, num, NULL)) AS D,
MAX(IF(seq % 5 = 0, num, NULL)) AS E
FROM
x1
GROUP BY group_no)
SELECT
A, B, C, D, E
FROM
x2
最终的实现效果>>>
A B C D E
------ ------ ------ ------ --------
1 2 3 4 5
10 9 8 7 6
11 12 13 14 15
20 19 18 17 16
21 22 23 24 25