Skip to content
Advertisement

Group numbers by 45 in mysql

I have a database in which I store wind direction readings by degrees. I need to do two things really, i need to group all readings by 45 (basically 45 degrees between “N”, “NE”, “E”, “SE”, “S”,”SW”,”W” and “NW”) and then i need to find the percentage of each of those groups in all readings.

This is where i’m stuck so far, i have managed only to group by reading_direction (missing the part how to group by 45) and managed to display percentage.

select 
    reading_winddirection, 
    count, 
    round(count / total * 100) postotak 
from 
    ( 
        select reading_winddirection, count(reading_winddirection) count 
        from simulation_readings  
        group by reading_winddirection 
    ) c 
    JOIN ( 
        select count(*) total from simulation_readings  
    ) t

This is my fiddle: MySql

In last 30ish minutes i have managed to figure out how to gorup by number ranges so this is half of my problem done:

SELECT `reading_winddirection`, 
   Count(*) AS num 
FROM   (SELECT CASE 
             WHEN `reading_winddirection` >= 1 
                  AND `reading_winddirection` < 45 THEN '0-45' 
             WHEN `reading_winddirection` >= 45 
                  AND `reading_winddirection` < 90 THEN '45-90' 
             WHEN `reading_winddirection` >= 90 
                  AND `reading_winddirection` < 135 THEN '90-135' 
             WHEN `reading_winddirection` >= 135 
                  AND `reading_winddirection` < 180 THEN '135-180' 
             WHEN `reading_winddirection` >= 180 
                  AND `reading_winddirection` < 225 THEN '180-225' 
             WHEN `reading_winddirection` >= 225 
                  AND `reading_winddirection` < 270 THEN '225-270' 
             WHEN `reading_winddirection` >= 270 
                  AND `reading_winddirection` < 315 THEN '270-315' 
             WHEN `reading_winddirection` >= 315 
                  AND `reading_winddirection` < 360 THEN '315-360' 
           end AS `reading_winddirection` 
    FROM   simulation_readings 
    WHERE  1) AS price_summaries 
GROUP  BY reading_winddirection 

I just need to find what is the percentage of all groups in count(*)

Advertisement

Answer

One easy solution would to divide reading_winddirection by 45, keep the integer part only, and use this for grouping.

select 
    case c.windgroup
        when 0 then 'N'
        when 1 then 'NE'
        when 2 then 'E'
        when 3 then 'SE'
        when 4 then 'S'
        when 5 then 'SW'
        when 6 then 'W'
        when 7 then 'NW'
    end windgroup,
    cnt,
    round(c.cnt / t.total * 100) postotak 
from 
    ( 
        select floor(reading_winddirection / 45) windgroup, count(*) cnt
        from simulation_readings  
        group by windgroup
    ) c 
    cross join ( 
        select count(*) total from simulation_readings  
    ) t

Note: if you are using MySQL 8.0, you can use window functions instead of joining to compute the total count:

select 
    case floor(reading_winddirection / 45)
        when 0 then 'N'
        when 1 then 'NE'
        when 2 then 'E'
        when 3 then 'SE'
        when 4 then 'S'
        when 5 then 'SW'
        when 6 then 'W'
        when 7 then 'NW'
    end windgroup,
    count(*) cnt,
    round(100 * count(*) / sum(count(*)) over()) postotak 
from simulation_readings  
group by windgroup

In this db fiddle, both queries yield:

windgroup | cnt | postotak
:-------- | --: | -------:
N         |   6 |       60
E         |   2 |       20
SE        |   1 |       10
SW        |   1 |       10
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement