Home > Net >  Count average with multiple conditions
Count average with multiple conditions

Time:12-17

I'm trying to create a query which allows to categorize the average percentage for specific data per month.

Here's how my dataset presents itself:

Date Name Group Percent
2022-01-21 name1 gr1 5.2
2022-01-22 name1 gr1 6.1
2022-01-26 name1 gr1 4.9
2022-02-01 name1 gr1 3.2
2022-02-03 name1 gr1 8.1
2022-01-22 name2 gr1 36.1
2022-01-25 name2 gr1 32.1
2022-02-10 name2 gr1 35.8
... ... ... ...

And here's what I want to obtain with my query (based on what I showed of the table):

Month <=25% 25<_<=50% 50<_<=75% 75<_<=100%
01 1 1 0 0
02 1 1 0 0
... ... ... ... ...

The result needs to:

  • Be ordered by month
  • Have the average use for each name counted and categorized

So far I know how to get the average of the Percent value per Name:

SELECT Name,
AVG(Percent) 
from `table`  
where Group = 'gr1' 
group by Name

and how to count iterations of Percent in the categories created for the query:

SELECT EXTRACT(MONTH FROM Date) as Month,
COUNT(CASE WHEN Percent <= 25 AND Group = 'gr1' THEN Name END) `_25`,
COUNT(CASE WHEN Percent > 25 AND Percent <= 50 AND Group = 'gr1' THEN Name END) `_50`,
COUNT(CASE WHEN Percent > 50 AND Percent <= 75 AND Group = 'gr1' THEN Name END) `_75`,
COUNT(CASE WHEN Percent > 75 AND Percent <= 100 AND Group = 'gr1' THEN Name END) `_100`,
FROM `table`
GROUP BY Month
ORDER BY Month

but this counts all iterations of every name where I want the average of those values.

I've been struggling to figure out how to combine the two queries or to create a new one that answers my need.

I'm working with the BigQuery service from Google Cloud

CodePudding user response:

This query produces the needed result, based on your example. So basically this combines your 2 queries using subquery, where the subquery is responsible to calculate AVG grouped by Name, Month and Group, and the outer query is for COUNT and "categorization"

SELECT
    Month,
    COUNT(CASE
      WHEN avg <= 25 THEN Name
    END) AS _25,
    COUNT(CASE
      WHEN avg  > 25
       AND avg  <= 50 THEN Name
    END) AS _50,
    COUNT(CASE
      WHEN avg  > 50
       AND avg  <= 75 THEN Name
    END) AS _75,
    COUNT(CASE
      WHEN avg  > 75
       AND avg <= 100 THEN Name
    END) AS _100
  FROM
    (
      SELECT
          EXTRACT(MONTH from Date) AS Month,
          Name,
          AVG(Percent) AS avg
        FROM
          table1
        GROUP BY Month, Name, Group
        HAVING Group = 'gr1'
    ) AS namegr
  GROUP BY Month

This is the result:

Month _25 _50 _75 _100
1 1 1 0 0
2 1 1 0 0

See also Fiddle (BUT on MySql) - http://sqlfiddle.com/#!9/16c5882/9

CodePudding user response:

You can use this query to Group By Month and each Name

SELECT CONCAT(EXTRACT(MONTH FROM Date), ', ', Name) AS DateAndName, 
CASE
    WHEN AVG(Percent) <= 25 THEN '1'
    ELSE '0'
END AS '<=25%',
CASE
    WHEN AVG(Percent) > 25 AND AVG(Percent) <= 50 THEN '1'
    ELSE '0'
END AS '25<_<=50%',
CASE
    WHEN AVG(Percent) > 50 AND AVG(Percent) <= 75 THEN '1'
    ELSE '0'
END AS '50<_<=75%',
CASE
    WHEN AVG(Percent) > 75 AND AVG(Percent) <= 100 THEN '1'
    ELSE '0'
END AS '75<_<=100%'
from DataTable /*change to your table name*/
group by EXTRACT(MONTH FROM Date), Name
order by DateAndName

It gives the following result:

DateAndName <=25% 25<_<=50% 50<_<=75% 75<_<=100%
1, name1 1 0 0 0
1, name2 0 1 0 0
2, name1 1 0 0 0
2, name2 0 1 0 0
  • Related