0

I have a MySQL table Section which has a column ordering. Some of the values of ordering are numbers and they are mutually exclusive (no two numbers are the same) and others are simple NULL.

Example:

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

Now I want to sort this table and get the following result:

(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

I.e. I want the rows that have a non-NULL value to appear in the given ordering, but the ones that have a NULL value to appear in the remaining ones, in random order (not predictable).

I am sure there are always enough NULL's to fill up the empty spaces.

I was thinking about first getting the ones with an order (WHERE ordering IS NOT NULL) and then the ones without an order (WHERE ordering IS NULL) and then somehow create an extra column that transforms the ones with NULL into a number that doesn't appear in the former.

Any help would be very much appreciated. I am using this in a project where there are sections that have a fixed position, but others can set to have a random order. Every time the page loads the random sections should be displayed, well, randomly.

4

2 回答 2

0

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

于 2013-07-20T15:45:43.900 回答
0

我找到了一个解决方案,但它相当笨拙和大。我将解释原因:

  • 获取从 1 到行数的数字列表(并将其称为all_rows)。
  • 获取排序不为空的部分。
  • 减去这两个,即从all_rows中获取不在现有排序列表中的那些,并给它们一个行号。(称之为未使用的行号
  • 获取排序为 NULL 的部分,将它们随机化并给它们一个行号。(称之为 nulls_with_row_numbers)
  • 将 used_row_numbers 与 nulls_with_row_numbers 连接,以获取所有排序为 NULL 并且现在具有缺失/未使用行号之一的部分。
  • 最后,将最后一个与已经有排序和 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)
于 2013-07-21T00:52:00.663 回答