简体   繁体   中英

How to Count the number of rows within each distinct group?

Given the following MySQL table:

| id | category | Hour | quantity|
|  0 | Sunday   |  10  |  32    |
|  0 | Sunday   |  11  |  19    |
|  0 | Sunday   |  12  |  48    |
|  0 | Sunday   |  19  |  7     |
|  1 | Monday   |  09  |  45    |
|  1 | Monday   |  10  |  17    |
|  1 | Monday   |  12  |  18    |
|  2 | Tuesday  |  08  |  16    |
|  2 | Tuesday  |  09  |  39    |
|  2 | Tuesday  |  10  |  24    |
|  2 | Tuesday  |  11  |  37    |
|  2 | Tuesday  |  12  |  40    |

I need to compute a fifth column which must be the division of "quantity" by the number of rows of id: for 0 there are 4 rows, for 1 3 rows, for 2 5 rows.

| id | category | Hour | quantity| avg |
|  0 | Sunday   |  10  |  32    |  8   |
|  0 | Sunday   |  11  |  19    | 4.75 | 
|  0 | Sunday   |  12  |  48    |  12  |
|  0 | Sunday   |  19  |  7     | 1.75 |
|  1 | Monday   |  09  |  45    |  15  |
|  1 | Monday   |  10  |  17    |  5.7 |
|  1 | Monday   |  12  |  18    |   6  |
|  2 | Tuesday  |  08  |  16    | 3.2  |
|  2 | Tuesday  |  09  |  39    | 7.8  |
|  2 | Tuesday  |  10  |  24    | 4.8  |
|  2 | Tuesday  |  11  |  37    | 7.4  |
|  2 | Tuesday  |  12  |  40    |  8   |

How can I get the result in a MySQL query?

The first table, is the result of this query:

 select id, category, Hour, count(*) as quantity
 FROM table_1
 GROUP by id, Hour ORDER by id, Hour;

This what I tried, in order to get the number of rows for the occurrence of each id, however I get a large number, the count of id=0 occurrences instead of id=0 rows in the previous query:

select  id, Hour,  count(id)  as q
FROM table_1 
GROUP by id 

This is mySql 5.6.

This is really quite ugly and cumbersome, but it was the only way to get the results without having a primary key to work with:

SELECT 
  t.id, 
  t.category, 
  t.hour, 
  quantity,  
  ROUND(quantity/count,2) AS avg
FROM table_1 t
    JOIN (SELECT 
              id, Hour, count(*) as quantity
             FROM table_1
            GROUP by id, category, Hour) AS qty
    ON t.id = qty.id AND t.hour = qty.hour

    JOIN (SELECT
            id, count(distinct hour) as count 
             FROM table_1
                GROUP BY id) as counts 
    ON t.id = counts.id
GROUP BY id, hour;

It seems to be working locally for me, at least, with guessing what your original dataset looks like.

There may well be a simpler way, however.

Edit: On second check, the 'quantity' subquery doesn't really add much that I can see, so this can be replaced with a 'count(*)', making a more optimal query:

SELECT 
  t.id, 
  t.category, 
  t.hour, 
  count(*) as quantity,  
  ROUND(count(*)/count,2) AS avg
FROM table_1 t
    JOIN (SELECT
            id, count(distinct hour) as count 
             FROM table_1
                GROUP BY id) as counts 
    ON t.id = counts.id
GROUP BY id, hour;

You need to do the counting in a subquery that just groups by id . Join the subquery to the main query and do the division.

SELECT id, category, hour, COUNT(*) AS quantity, COUNT(*)/count AS avg
FROM table_1
JOIN (SELECT id, COUNT(DISTINCT hour) AS count
      FROM table_1
      GROUP BY id) AS counts 
    ON table_1.id = counts.id
GROUP BY table_1.id, table_1.hour
ORDER BY table_1.id, table_1.hour

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM