Reputation: 824
I have the below query which is outputting the below results:
SELECT
a,
b,
COUNT(1) count,
round(RATIO_TO_REPORT(COUNT(1)) OVER() * 100, 2) perc
FROM
t1
WHERE
condition1
GROUP BY
a,
b
ORDER BY
COUNT(1) DESC
A | B | COUNT | PERC |
---|---|---|---|
Correct | Correct | 968272 | 89.37 |
Mismatch | Correct | 52620 | 4.86 |
Correct | NO VALUES | 44630 | 4.12 |
Correct | Mismatch | 10722 | 0.99 |
NO VALUES | NO VALUES | 6217 | 0.57 |
Mismatch | Mismatch | 662 | 0.06 |
NO VALUES | Mismatch | 294 | 0.03 |
How could I get the below enhancing the query?
A | B | COUNT | PERC | COUNT_TOTAL_A | PERC_PARTITION_BY_A |
---|---|---|---|---|---|
Correct | Correct | 968272 | 89.37 | 1023624 | 94.59 |
Mismatch | Correct | 52620 | 4.86 | 53282 | 98.76 |
Correct | NO VALUES | 44630 | 4.12 | 1023624 | 4.36 |
Correct | Mismatch | 10722 | 0.99 | 1023624 | 1.05 |
NO VALUES | NO VALUES | 6217 | 0.57 | 6511 | 95.48 |
Mismatch | Mismatch | 662 | 0.06 | 53282 | 1.24 |
NO VALUES | Mismatch | 294 | 0.03 | 6511 | 4.52 |
Upvotes: 0
Views: 95
Reputation: 59455
Try this one:
WITH t AS
(SELECT a, b, COUNT(1) AS cnt FROM T1 WHERE condition1 GROUP BY a, b)
SELECT DISTINCT
a,
b,
SUM(cnt) OVER (PARTITION BY A, B) COUNT,
ROUND(RATIO_TO_REPORT(cnt) OVER () * 100, 2) perc,
SUM(cnt) OVER (PARTITION BY A),
ROUND(RATIO_TO_REPORT(cnt) OVER(PARTITION BY A) * 100, 2)
FROM t
ORDER BY 3 DESC
Upvotes: 1
Reputation: 21075
If you are in doubt how to combine the aggregation with the analytical function on different levels, simple split it in separate CTE
The first CTE calulates the overall count and percentage, the second the same for the A
column.
Then join both results to get the complete report.
with cnt as (
select a,b, count(*) count,
round(RATIO_TO_REPORT(COUNT(1)) OVER() * 100, 2) perc
from tab t1
where 1=1 /* some condition 1 */
group by a,b),
cnt_a as (
select a, count(*) count,
round(RATIO_TO_REPORT(COUNT(1)) OVER() * 100, 2) perc
from tab t1
where 1=1 /* some condition 1 */
group by a )
select
cnt.a, cnt.b, cnt.count, cnt.perc,
cnt_a.count as count_by_a,
cnt_a.perc as perc_by_a
from cnt
join cnt_a on cnt.a = cnt_a.a
order by 3 desc;
A B COUNT PERC COUNT_BY_A PERC_BY_A
--------- --------- ---------- ---------- ---------- ----------
Correct Correct 968272 89,37 1023624 94,48
Mismatch Correct 52620 4,86 53282 4,92
Correct NO VALUES 44630 4,12 1023624 94,48
Correct Mismatch 10722 ,99 1023624 94,48
NO VALUES NO VALUES 6217 ,57 6511 ,6
Mismatch Mismatch 662 ,06 53282 4,92
NO VALUES Mismatch 294 ,03 6511 ,6
I'm not claimint that there is a simpler solution with one pass, but this solution works.
Interesting is also why you in your sample data expects e.g. for Correct
three different values of PERC_PARTITION_BY_A
Upvotes: 0
Reputation: 1269843
This answers the original version of the question.
If I understand correctly, you want the ratio of the value of b
to the overall count. If so, just calculate the ratio directly:
SELECT a, b, COUNT(1) as count,
SUM(SUM(CASE WHEN b = 'Correct' THEN 1 ELSE ) END)) OVER () * 100.0 / COUNT(*) as perc
FROM t1
WHERE condition1
GROUP BY a, b
ORDER BY COUNT(1) DESC;
Upvotes: 1