MySQL中的连锁范围描述

时间:2010-07-17 02:04:52

标签: sql mysql

我在表格中有数据如下:

+---+----+
| a |  b |
+---+----+
| a |  1 |
| a |  2 |
| a |  4 |
| a |  5 |
| b |  1 |
| b |  3 |
| b |  5 |
| c |  5 |
| c |  4 |
| c |  3 |
| c |  2 |
| c |  1 |
+---+----+

我想生成一个SQL查询,输出如下数据:

+---+-----------+
| a |  1-2, 4-5 |
| b |  1,3,5    |
| c |  1-5      |
+---+-----------+

有没有办法在SQL中完全执行此操作(特别是MySQL 5.1?)

我最接近的是select a, concat(min(b), "-", max(b)) from test group by a;,但这并未考虑范围内的差距。

2 个答案:

答案 0 :(得分:3)

使用:

     SELECT a, GROUP_CONCAT(x.island)
         FROM (SELECT y.a,
                               CASE
                                  WHEN MIN(y.b) = MAX(y.b) THEN
                                    CAST(MIN(y.b) AS VARCHAR(10))
                                  ELSE
                                    CONCAT(MIN(y.b), '-', MAX(y.b))
                               END AS island
                      FROM (SELECT t.a, t.b,
                                            CASE
                                                WHEN @prev_b = t.b -1 THEN
                                                    @group_rank
                                                ELSE
                                                  @group_rank := @group_rank + 1
                                            END AS blah,
                                            @prev_b := t.b
                                  FROM TABLE t
                                  JOIN (SELECT @group_rank := 1, @prev_b := 0) r
                           ORDER BY t.a, t.b) y
               GROUP BY y.a, y.blah) x  
GROUP BY a

这个想法是,如果您为一个组序列值分配一个值,那么您可以使用MIN / MAX来获得适当的vlalues。 IE:

a  |  b | blah
---------------
a  |  1 | 1
a  |  2 | 1
a  |  4 | 2
a  |  5 | 2

答案 1 :(得分:1)

我还发现马丁史密斯对另一个问题的答案很有帮助:

printing restaurant opening hours from a database table in human readable format using php