Calculate percentage of SQL Group BY - sql

The following SQL statement:
SELECT FTR, COUNT(FTR)
FROM football_data
WHERE Matchday >= '2019-01-18'
GROUP BY FTR
Returns the following result:
Now I'm trying to get a percentage for each of those COUNT(FTR)'s.
So the sum of those 3 numbers is 153. Now I would like to get the percentage of them

You can use window functions, if I understand correctly:
SELECT FTR, COUNT(*),
COUNT(*) * 1.0 / SUM(COUNT(*)) OVER () as ratio
FROM football_data
WHERE Matchday >= '2019-01-18'
GROUP BY FTR;

Related

SQL aggregated subquery - Athena

Using AWS Athena I want to get total recovered per day by getting total recovered amount / total advances
here is code:
SELECT a.advance_date
,sum(a.advance_amount) as "advance_amount"
,sum(a.advance_fee) as "advance_fee"
,(SELECT
sum(credit_recovered+fee_recovered) / (a.advance_amount+a.advance_fee)
FROM ncmxmy.ageing_recovery_raw_parquet
WHERE advance_date = a.advance_date
AND date(recovery_date) <= DATE_ADD('day', 0, a.advance_date)
) as "day_0"
FROM ageing_summary_advance_parquet a
GROUP BY a.advance_date
ORDER BY a.advance_date
I am getting an error
"("sum"((credit_recovered + fee_recovered)) / (a.advance_amount + a.advance_fee))' must be an aggregate expression or appear in GROUP BY clause"
Your division gives the error because the denominator tries to use individual columns from the ageing_summary_advance_parquet table. In my perception of the query, you need to divide by the grouped sum of advance_amount and advance_fee columns. In that case, we can merge two grouped sets of data by advance_date into the division. Please let me know if this query helps:
WITH cte1 (sum_adv_date, advance_date) as
(SELECT
sum(credit_recovered+fee_recovered) as sum_adv_date, advance_date
FROM ncmxmy.ageing_recovery_raw_parquet
WHERE date(recovery_date) <= DATE_ADD('day', 0, advance_date)
GROUP BY advance_date
),
cte2 (advance_date, advance_amount, advance_fee) as
(SELECT
a.advance_date
,sum(a.advance_amount) as "advance_amount"
,sum(a.advance_fee) as "advance_fee"
FROM ageing_summary_advance_parquet a
GROUP BY a.advance_date
)
SELECT cte2.advance_amount, cte2.advance_fee,
(cte1.sum_adv_date/(cte2.advance_amount+cte2.advance_fee)) as "day_0"
FROM cte1 inner join cte2 on cte1.advance_date = cte2.advance_date
ORDER BY cte1.advance_date

Calculating % of COUNT with groupby function in bigquery

Running into some issues figuring out how to add in an extra column that will give me the percentage of the total of the aggregate of the count function. The query I have looks like this:
Select
count(*) AS num_rides,
member_casual
FROM `2020_bikeshare_data`
GROUP BY member_casual
ORDER BY num_rides DESC
And returns me this result:
num_rides
member_casual
2134988
member
1341217
casual
And what I'd like to do is add a 3rd column that lists the percent of the total each membership makes up
num_rides
member_casual
perc_tot
2134988
member
61.4%
1341217
casual
38.6
thoughts?
You window functions:
SELECT member_casual,
COUNT(*) AS num_rides,
COUNT(*) * 1.0 / SUM(COUNT(*)) OVER ()
FROM `2020_bikeshare_data`
GROUP BY member_casual
ORDER BY num_rides DESC;
No subquery is needed.
Consider below approach
select distinct member_casual,
count(num_rides) over type as num_rides,
round(count(num_rides) over type * 100.0 / count(num_rides) over(), 2) as perc_tot
from `2020_bikeshare_data`
window type as (partition by member_casual)
# order by num_rides desc
if applied to sample data in your question - output is
The simplest way is use a subquery as part of the column expression to calculate your percentage:
select
count(1) as num_rides,
member_casual,
sum(100) / (select sum(1.0) from `2020_bikeshare_data`) as perc_tot -- return as percentage
from
`2020_bikeshare_data`
group by
member_casual
Using the subquery, get the total number of rows and calculate the percentage accordingly.
Select
count(*) AS num_rides,
member_casual,
Concat(count(*) * 100 / totalRecord,' %') as perc_tot
FROM (SELECT *,COUNT(*) as totalRecord FROM `2020_bikeshare_data`)
GROUP BY member_casual
or
Select
count(*) AS num_rides,
member_casual,
Concat(count(*) * 100 / (SELECT COUNT(*) FROM `2020_bikeshare_data`) ,' %') as perc_tot
FROM `2020_bikeshare_data`
GROUP BY member_casual
In addition to the other answers, you can also break this down into simple SQL (without window functions) by organizing with CTEs.
with
data as (select * from `2020_bikeshare_data`),
total as (select count(*) as ride_count from data),
by_type as (select member_casual, count(*) as ride_count from data group by 1)
select
member_casual,
by_type.ride_count as num_rides,
by_type.ride_count / total.ride_count as perc_tot
from by_type
cross join total
In my opinion, this is much easier to see the perc_tot calculation.

Calculate the percentage in the same SELECT in a query

I am trying to calculate the percentage in the same SELECT in a query of a table in the SQL database.
In the table below, column 3 would have the function of taking the total sum of column 2 *** (15973,1748209 + 1947,18266487 = 17830,35749) *** and dividing by the value of the respective line (in the case of line 1 it is divide by 15913,1748209), but I still can't, can someone help me? Thank you very much in advance
SELECT
Tab_Dados_Escolha.Parametro,
Sum(Tab_Dados_Escolha.Metrica) As Metrica,
Sum(Tab_Dados_Escolha.Metrica) / < % total % > As Porcentagem
FROM
Tab_Dados_Escolha
WHERE
(
Tab_Dados_Escolha.E3TimeStamp >= #<%inicio%>#
AND Tab_Dados_Escolha.E3TimeStamp <= #<%fim%>#
)
GROUP BY
Tab_Dados_Escolha.Parametro
Here is how you can do it using a window function:
SELECT
Tab_Dados_Escolha.Parametro,
sum(Tab_Dados_Escolha.Metrica) As Metrica,
sum(Tab_Dados_Escolha.Metrica) * 100.0 / sum(sum(Tab_Dados_Escolha.Metrica)) over() As Porcentagem
FROM Tab_Dados_Escolha
WHERE
Tab_Dados_Escolha.E3TimeStamp >= #<%inicio%>#
AND Tab_Dados_Escolha.E3TimeStamp <= #<%fim%>#
GROUP BY Tab_Dados_Escolha.Parametro
I think you want to use the sum() over () window function.
SELECT Tab_Dados_Escolha.Parametro
, SUM(Tab_Dados_Escolha.Metrica) AS Metrica
, SUM(Tab_Dados_Escolha.Metrica)/SUM(Tab_Dados_Escolha.Metrica) OVER (PARTITION BY Tab_Dados_Escolha.Parametro) AS Porcentagem
FROM Tab_Dados_Escolha
WHERE (Tab_Dados_Escolha.E3TimeStamp >= #<%inicio%># AND Tab_Dados_Escolha.E3TimeStamp <= #<%fim%>#)
GROUP BY Tab_Dados_Escolha.Parametro;

How to divide by the result of another query

This is a separate question based on a previous post:
[Link] How to calculate Grand Totals when using OVER (partition by ...) using Oracle SQL
I am using the following Oracle SQL query:
SELECT JOB_GROUP,
SUM(PEOPLE) AS CURRENT_PEOPLE
SUM(PEOPLE) / '100' AS RATIO
FROM MY_VIEW
WHERE MONTH = '01-DEC-2013'
GROUP BY ROLLUP (OB_GROUP)
ORDER BY RATIO DESC;
This query gives me an output like this..
JOB_GROUP CURRENT_PEOPLE RATIO
WORKER1 100 1.0
WORKER2 30 .3
WORKER3 40 .4
WORKER4 25 .25
WORKER5 30 .30
(NULL) 225 2.25
I need to be able to divide the sum of all of the ratios into the sum of the ratios where job_group = 'WORKER1', WORKER2, WORKER4. For Example, we can have 5 different job_groups, but I only need the sum of the ratio for 1, 2 and 4. I suspect this is some type of subquery, but have not been able to get the right result yet.
The equation would look like sum(ratios) / sum(ratio) where worker, 1,2,4. 2.25 / (1.0 + .3 + .25) = .80
Thanks for any help you can provide,
The following uses an analytic function to get the number of worker1s:
select JOB_GROUP, CURRENT_PEOPLE,
CURRENT_PEOPLE / sum(job_group = 'WORKER1' then CURRENT_PEOPLE end) over () as Ratio
from (SELECT JOB_GROUP,
SUM(PEOPLE) AS CURRENT_PEOPLE
FROM my_view
WHERE MONTH = '01-DEC-2013'
GROUP BY ROLLUP (JOB_GROUP)
) t
ORDER BY RATIO DESC;

not single-group grouping function while using regr_slope

HI I try to run :
select
year,
regr_slope(sum(sale_count),year) as slope,
from products
group by year
It throws "00937. 00000 - "not a single-group group function"" .When i delete year from select clause problem disapears. Shouldn't I be able to select column with which I'm grouping?
Oracle 11.2 sqldeveloper
ty for help !
It's because you're attempting to use a function (REGR_SLOPE) that can be either an aggregate (or analytical) function on the result of another aggregate (SUM) - use:
SELECT x.year,
REGR_SLOPE(sum_sales, x.year) AS slope
FROM (SELECT y.year,
SUM(y.sale_count) AS sum_sales
FROM PRODUCTS y
GROUP BY y.year) x
GROUP BY x.year
Alternative using WITH clause (Oracle 9i+):
WITH sums AS (
SELECT y.year,
SUM(y.sale_count)
FROM PRODUCTS y
GROUP BY y.year)
SELECT x.year,
REGR_SLOPE(sum_sales, x.year) AS slope
FROM sums x
GROUP BY x.year
Did you try it like this?
select
a.year
, regr_slope(a.sale_count,a.year) as slope,
from (SELECT year
, sum(sale_count) sale_count
FROM products
GROUP BY year) a