我知道这个问题已经被问过几次了,但是它总是在某些复杂的情况下或在理论上是不完整的。
我正在寻找一个通用的答案,例如数学公式,以便为我和将来的搜索服务。
那么,让我们看看下面的桌子...
col_a | col_b | prt_x | prt_y | ord_u | ord_w
-------+--------+--------+--------+--------+--------
row_a1 | row_b1 | row_x1 | row_y1 | row_u1 | row_w1
row_a2 | row_b2 | row_x2 | row_y2 | row_u2 | row_w2
row_a3 | row_b3 | row_x3 | row_y3 | row_u3 | row_w3
row_a4 | row_b4 | row_x4 | row_y4 | row_u4 | row_w4
假设我们要重写下面针对MySQL V5.7的命令。
1-ROW_NUMBER,分区数为
SELECT col_a, col_b, ROW_NUMBER() OVER(PARTITION BY prt_x)
FROM tbl
解决方案:
SELECT
col_a,
col_b,
@row_num := IF(@part1=prt_x, @row_num + 1, 1) AS R,
@part1 := prt_x
FROM tbl
CROSS JOIN (SELECT @row_num := 1, @part1 := NULL) AS tbl_aux
2-ROW_NUMBER具有两个分区,
SELECT col_a, col_b, ROW_NUMBER() OVER(PARTITION BY prt_x, prt_y)
FROM tbl
解决方案:
SELECT
col_a,
col_b,
@row_num := IF(@part1=prt_x AND @part2=prt_y, @row_num + 1, 1) AS ROW_NUMBER,
@part1 := prt_x,
@part2 := prt_y
FROM tbl
CROSS JOIN (SELECT @row_num := 1, @part1 := NULL, @part2 := NULL) AS tbl_aux
3-ROW_NUMBER(其中有一个订单)
SELECT col_a, col_b, ROW_NUMBER() OVER(PARTITION BY prt_x, prt_y, ORDER BY ord_u)
FROM tbl
解决方案:
SELECT
col_a,
col_b,
@row_num := IF(@part1=prt_x AND @part2=prt_y, @row_num + 1, 1) AS ROW_NUMBER,
@part1 := prt_x,
@part2 := prt_y
FROM tbl
CROSS JOIN (SELECT @row_num := 1, @part1 := NULL, @part2 := NULL) AS tbl_aux ORDER BY ord_u ASC
4-ROW_NUMBER有两个订单
SELECT col_a, col_b, ROW_NUMBER() OVER(PARTITION BY prt_x, prt_y, ORDER BY ord_u, ord_v)
FROM tbl
解决方案
SELECT
col_a,
col_b,
@row_num := IF(@part1=prt_x AND @part2=prt_y, @row_num + 1, 1) AS ROW_NUMBER,
@part1 := prt_x,
@part2 := prt_y
FROM tbl
CROSS JOIN (SELECT @row_num := 1, @part1 := NULL, @part2 := NULL) AS tbl_aux ORDER BY ord_u ASC, ord_v ASC
5-ROW_NUMBER(按RAND排序)
SELECT col_a, col_b, ROW_NUMBER() OVER(PARTITION BY prt_x, prt_y, ORDER BY ord_u, RAND())
FROM tbl
解决方案:
SELECT
col_a,
col_b,
@row_num := IF(@part1=prt_x AND @part2=prt_y, @row_num + 1, 1) AS ROW_NUMBER,
@part1 := prt_x,
@part2 := prt_y
FROM tbl
CROSS JOIN (SELECT @row_num := 1, @part1 := NULL, @part2 := NULL) AS tbl_aux ORDER BY ord_u ASC, RAND()
6-ROW_NUMBER,按MOD排序
SELECT col_a, col_b, ROW_NUMBER() OVER(PARTITION BY prt_x, prt_y, ORDER BY ord_u, MOD(n1, n2))
FROM tbl
解决方案:
SELECT
col_a,
col_b,
@row_num := IF(@part1=prt_x AND @part2=prt_y, @row_num + 1, 1) AS ROW_NUMBER,
@part1 := prt_x,
@part2 := prt_y
FROM tbl
CROSS JOIN (SELECT @row_num := 1, @part1 := NULL, @part2 := NULL) AS tbl_aux ORDER BY ord_u ASC, MOD(n1, n2)