0

我不是 MySql 的专家。我正在尝试将表中的数据拆分为基于account_no. 这是我的桌子。

mysql> select * from manager;
+----+-------+------------+
| id | name  | account_no |
+----+-------+------------+
|  1 | John  |          5 |
|  2 | Peter |         15 |
|  3 | Tony  |         18 |
|  4 | Mac   |         35 |
|  5 | Max   |         55 |
|  6 | Smith |         58 |
+----+-------+------------+

如您所见,account_no是一个正数。我想根据account_no将这些记录分成 10 批并显示该范围内的计数。 对于010 之间

的示例, 1120 之间只有1条记录2130 之间有2条记录没有记录* (所以应该省略。) * 等等...实际上我希望得到一个输出像这样。






+-------------+-----------+-------+
| range_start | range_end | count |
+-------------+-----------+-------+
|           1 | 10        |     1 | -> because there is 1 record between 1 and 10
|          11 | 20        |     2 | -> because there are 2 records between 11 and 20
|          31 | 40        |     1 | -> because there is 1 record between 31 and 40
|          51 | 60        |     2 | -> because there are 2 records between 51 and 60
+-------------+-----------+-------+

我尝试了几种组合,但所有组合都只给我一行结果。
有谁能够帮助我?

4

4 回答 4

5

我的建议是创建一个包含范围的表 -startRangeendRange

CREATE TABLE range_values   (`startRange` int, `endRange` int) ;

INSERT INTO range_values(`startRange`, `endRange`)
VALUES (1, 10), (11, 20), (21, 30), (31, 40), (51, 60);

创建表后,您可以轻松地加入表以获取计数。

select r.startRange,
  r.endRange,
  count(m.account_no) totalCount
from manager m
inner join range_values r
  on m.account_no >=startrange
  and m.account_no <= endrange
group by r.startRange, r.endRange

请参阅SQL Fiddle with Demo

该表的好处是您无需对范围值进行编码,并且无需更改代码即可轻松更新表中的范围。

此查询返回:

| STARTRANGE | ENDRANGE | TOTALCOUNT |
--------------------------------------
|          1 |       10 |          1 |
|         11 |       20 |          2 |
|         31 |       40 |          1 |
|         51 |       60 |          2 |

如果您不想创建新表,则可以使用类似于以下内容的内容:

select startrange,
  endrange,
  count(m.account_no) TotalCount
from manager m
inner join
(
  select 1 startRange, 10 endrange union all
  select 11 startRange, 20 endrange union all
  select 21 startRange, 30 endrange union all
  select 31 startRange, 40 endrange union all
  select 41 startRange, 50 endrange union all
  select 51 startRange, 60 endrange
) r
  on m.account_no >=startrange
  and m.account_no <= endrange
group by r.startRange, r.endRange

请参阅带有演示的 SQL Fiddle

于 2013-03-07T16:35:14.150 回答
1

这应该为您提供您想要的输出,并在计数列中包含零范围。

SET @rs = 0; SELECT IF(@rs, @rs := @rs + 10, @rs := 1) AS range_start, @rs + 9 AS range_end, (SELECT COUNT(id) FROM manager WHERE account_no >= @rs AND account_no <= @rs + 9) AS `count` FROM manager;

省略计数列中为零的行;

SET @rs = 0; SELECT * FROM (SELECT IF(@rs, @rs := @rs + 10, @rs := 1) AS range_start, @rs + 9 AS range_end, (SELECT COUNT(id) FROM manager WHERE account_no >= @rs AND account_no <= @rs + 9) AS `count` FROM manager) AS data WHERE `count` > 0;
于 2013-03-07T16:51:23.547 回答
0

尝试这样的事情:

SELECT
    CASE
        WHEN range_start < 10 THEN 'Under 10'
        WHEN range_start BETWEEN 11 and 29 THEN '11 - 29'
        (...more ranges...)
    END as range,
    COUNT(*) AS count
    GROUP BY range
    ORDER BY range
于 2013-03-07T16:14:29.380 回答
0

您应该在 MSSQL 中使用类似于 rank 和 dense_rank 的函数,您可以从以下链接开始在 MySQL 中实现它们:

http://www.folkstalk.com/2013/03/grouped-dense-rank-function-mysql-sql-query.html

于 2016-10-09T21:24:26.740 回答