使用给定的排序和空随机值对MySQL表进行排序

时间:2013-07-20 15:30:30

标签: mysql sorting

我有一个MySQL表部分,其中有一列排序排序的某些值是数字,它们是互斥的(没有两个数字相同),其他值是简单的 NULL

示例:

ID Ordering
-- --------
1  NULL
2  2
3  5
4  NULL
5  NULL
6  3
7  NULL

现在我想对此表进行排序并获得以下结果:

(ROW NUMBER) ID  Ordering
------------ --  -------- ------------
1            4   NULL
2            2   2
3            6   3
4            5   NULL
5            3   5
6            7   NULL
7            1   NULL

即。我希望具有非NULL值的行显示在给定的排序中,但具有 NULL 值的行以随机顺序显示在其余的值中(不可预测)。

我确信总有足够的NULL来填充空格。

我正在考虑首先获取带有顺序的那些(WHERE命令IS NOT NULL)然后没有命令的那些(WHERE排序IS NULL)然后以某种方式创建一个额外的列,将具有NULL的那些转换为数字这不会出现在前者中。

非常感谢任何帮助。我在一个项目中使用它,其中有一些部分具有固定的位置,但其他部分可以设置为随机顺序。每次页面加载时,随机部分都应该随机显示。

2 个答案:

答案 0 :(得分:0)

您可以使用nvl()函数将NULL结果更改为0以外的其他值

答案 1 :(得分:0)

我找到了一个解决方案,但它相当笨拙而且很大。我会解释一下推理:

  • 获取从1到行数的数字列表(并将其命名为 all_rows )。
  • 获取排序为非空的部分。
  • 将这两者相提并论,即从 all_rows 获取不在已有排序列表中的那些,并为其提供行号。 (称之为 unused_row_numbers
  • 获取排序为NULL的部分,随机化它们并给它们一个行号。 (称之为nulls_with_row_numbers)
  • 使用nulls_with_row_numbers连接unused_row_numbers以获取排序为NULL的所有Sections,现在有一个缺失/未使用的行号。
  • 最后,将最后一个与已经有订单和tataaaa的那个联合起来......

现在这是SQL:

SELECT row_number, id
FROM (
  SELECT @curRow2 := @curRow2 + 1 AS row_number2, row_number
  FROM (
    SELECT @curRow := @curRow + 1 AS row_number
    FROM Sections
    JOIN (SELECT @curRow := 0) r
  ) all_rows
  JOIN (SELECT @curRow2 := 0) r
  WHERE all_rows.row_number NOT IN (
    SELECT ordering
    FROM Sections
    WHERE ordering IS NOT NULL
  )) unused_row_numbers,
(
  SELECT @curRow3 := @curRow3 + 1 AS row_number3, id
  FROM (
    SELECT ordering, id
    FROM Sections
    WHERE ordering IS NULL
    ORDER BY RAND()
  ) randomized_nulls
  JOIN (SELECT @curRow3 := 0) r
) nulls_with_row_numbers
WHERE unused_row_numbers.row_number2 = nulls_with_row_numbers.row_number3

UNION

SELECT ordering AS row_number, id
FROM Sections
WHERE ordering IS NOT NULL

ORDER BY row_number

每次都会给出不同的结果。示例结果:

ROW_NUMBER ID
---------- --
1          1  (random)
2          2  (always second position)
3          6  (always third position)
4          4  (random)
5          3  (random)
6          5  (always sixth position)
7          7  (random)