2

我的列表是一个无限的宇宙,举个例子,我想拿一张这样的表:

+--------+------+
| 集团 | 姓名 |
+--------+------+
| 1 | 一个 |
| 1 | 乙|
| 1 | C |
| 1 | D |
| 1 | E |
| 1 | F |
| 1 | 克|
| 1 | H |
| 1 | 我 |
| 2 | Ĵ |
| 2 | 大号 |
| 2 | 中号 |
| 3 | N |
| 4 | ○ |
| 4 | 磷 |
| 4 | 问 |
| 4 | 右 |
| 4 | 小号 |
| 5 | 你 |
| 6 | 五 |
+--------+------+

并运行按以下顺序生成结果的查询:

+--------+------+
| 集团 | 姓名 |
+--------+------+
| 1 | 一个 |
| 2 | Ĵ |
| 3 | N |
| 4 | ○ |
| 5 | 你 |
| 6 | 五 |
| 1 | 乙|
| 2 | 大号 |
| 4 | 磷 |
| 1 | C |
| 2 | 中号 |
| 4 | 问 |
| 1 | D |
| 4 | 右 |
| 1 | E |
| 4 | 小号 |
| 1 | F |
| 1 | 克|
| 1 | H |
| 1 | 我 |
+--------+------+
4

1 回答 1

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会因此保存一行的值。

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

于 2014-03-14T14:20:20.207 回答