MySQL中有没有办法在变量Universe中的特定字段上进行“循环”ORDER BY?

时间:2014-03-14 14:03:34

标签: mysql sql-order-by round-robin

我的列表是一个无限的宇宙,作为一个例子,我想采取这样一个表:

+-------+------+
| group | name |
+-------+------+
|     1 | A    |
|     1 | B    |
|     1 | C    |
|     1 | D    |
|     1 | E    |
|     1 | F    |
|     1 | G    |
|     1 | H    |
|     1 | I    |
|     2 | J    |
|     2 | L    |
|     2 | M    |
|     3 | N    |
|     4 | O    |
|     4 | P    |
|     4 | Q    |
|     4 | R    |
|     4 | S    |
|     5 | U    |
|     6 | V    |
+-------+------+

运行一个按此顺序生成结果的查询:

+-------+------+
| group | name |
+-------+------+
|     1 | A    |
|     2 | J    |
|     3 | N    |
|     4 | O    |
|     5 | U    |
|     6 | V    |
|     1 | B    |
|     2 | L    |
|     4 | P    |
|     1 | C    |
|     2 | M    |
|     4 | Q    |
|     1 | D    |
|     4 | R    |
|     1 | E    |
|     4 | S    |
|     1 | F    |
|     1 | G    |
|     1 | H    |
|     1 | I    |
+-------+------+

1 个答案:

答案 0 :(得分:4)

select `group`, name from (
  select 
  t.*,
  @rn := if(`group` != @ng, 1, @rn + 1) as ng,
  @ng := `group`
  from t
  , (select @rn:=0, @ng:=null) v
  order by `group`, name
) sq
order by ng, `group`, name

稍微解释一下......

  , (select @rn:=0, @ng:=null) v

这一行只是一种动态初始化变量的奇特方式。这与省略此行相同,但在SET @rn := 0; SET @ng := NULL;之前有SELECT

然后子查询中的ORDER BY非常重要。在关系数据库中,除非您指定它,否则没有订单。

下面

  @rn := if(`group` != @ng, 1, @rn + 1) as ng,
  @ng := `group`

如果当前行中group的值与@ng的值不同,则第一行是简单检查。如果是,请将1分配给@rn,如果不是,请增加@rn SELECT子句中列的顺序非常重要。 MySQL逐个处理它们。在第二行中,我们将当前行的group值分配给@ng。当查询处理表格的下一行时,在上述两行的第一行中,@ng将保留上一个行的值。

外部选择只是化妆品,以隐藏不必要的列。随意询问是否还有什么不清楚。哦,here你可以在MySQL中阅读更多有关用户定义变量的信息 但请注意,需要变量是个例外。它们通常会导致全表扫描。无论你想用select语句中的变量实现什么,通常都可以在应用程序级别而不是数据库级别上完成。