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