我手头有问题,那就是根据单个列的值以数字模式/序列获取结果集。
说我有下表:
+-------+
| val |
+-------+
| 1 |
| 1 |
| 1 |
| 1 |
| 2 |
| 2 |
| 2 |
| 2 |
| 3 |
| 3 |
| 3 |
| 3 |
+-------+
我怎样才能这样做:
+-------+
| val |
+-------+
| 1 |
| 2 |
| 3 |
| 1 |
| 2 |
| 3 |
| 1 |
| 2 |
| 3 |
| 1 |
| 2 |
| 3 |
+-------+
如果其中一个值不足以填补空白,那么预期的行为是什么呢?假设我们将3个中的两个替换为8个
+-------+
| val |
+-------+
| 1 |
| 1 |
| 1 |
| 1 |
| 2 |
| 2 |
| 2 |
| 2 |
| 3 |
| 3 |
| 8 |
| 8 |
+-------+
我仍然期望它以最小的数字序列,然后是最大的,然后是最小的,然后是最大的。
+-------+
| val |
+-------+
| 1 |
| 2 |
| 3 |
| 8 |
| 1 |
| 2 |
| 3 |
| 8 |
| 1 |
| 2 |
| 1 |
| 2 |
+-------+
答案 0 :(得分:1)
这就是我们所谓的主要rownum
黑客攻击。假设您的表名为t,您的值列名为val。这将给出您正在寻找的结果。
SELECT val /* step 6 */
FROM
(SELECT A.val,
CASE
WHEN A.val <> IFNULL(B.val,-1) THEN @q:=0 /* step 4 */
ELSE @q:=@q+1 /* step 4 */
END AS seq /* step 4 */
FROM
(SELECT @q:=0)r,
(SELECT /* step 1 */
@a:=@a+1 AS n, /* step 1 */
val /* step 1 */
FROM (SELECT @a:= 0)r, T /* step 1 */
ORDER BY val) A /* step 1 */
LEFT JOIN
(SELECT /* step 2, like step 1 */
@b:=@b+1 AS n,
val
FROM (SELECT @b:= 0)r, T
ORDER BY val) B
ON B.n = A.n-1 /* step 3 */
ORDER BY seq,val) s /* step 5 */
一两句解释:
我们需要将你的val表变为 一个val,n表(其中n是行 数)
然后我们需要其中两个 独立行号@a和@b
然后我们需要将它们连接在一起 使用row = row-1偏移量进行比较 相邻的val列。
然后我们需要应用一个序列 每个val列的编号,即 复位。也就是说,我们需要给予 序列号1,2,3到1s,然后是2s, 等
然后我们需要按seq排序 VAL。
然后我们需要隐藏seqs。
看见......
Hack hack!