问题
I'm trying to quantify some things. Here's a sample (simplified of course):
tblParent: { Number, Name }
tblChild: { Number, Name, ParentNumber, Criterion }
I'd like to count the total number of Children with the same ParentNumber
(easy using a Group By and a Count(1) ), but the problem is comparing that number with the number of children with the same ParentNumber
who have Criterion = "Something"
.
Here's what I have so far:
SELECT "Criterion = 1" AS CritDesc,
COUNT(1) AS Total,
ParentNumber AS Parent,
( COUNT(1) / (SELECT Total FROM [TotalCountingQuery]) ) AS Percentage
FROM tblChild
WHERE Criterion = 1
GROUP BY ParentNumber;
[TotalCountingQuery]
simply counts all Children with each ParentNumber and puts that total into Total
SELECT COUNT(1) AS Total FROM tblChild GROUP BY ParentNumber;
So I'm trying to use that TOTAL count and figure out how many (as a percentage) have Criterion=1. But since it is using a subquery, the subquery cannot return more than one Total. I need it to return the total for each ParentNumber, to be used in the Percentage calc for each Child having that ParentNumber.
End result should be:
CritDesc | Total | Parent | Percentage
```````````````````````````````````````````````````````
Criterion=1| 2 | 45011 | 0.333 // Means there should be 6 Children with 45011 as parent
Criterion=1| 4 | 43255 | 0.9
Criterion=1| 1 | 59056 | 0.44
I have several of these queries which I union in a report to produce a full report, grouped by Parent, showing all "Criterion=X" for all Parents. That's working, I just need the above working.
Ideas?
EDIT: My attempt at a join for this purpose:
SELECT "Criterion=1" AS CritDesc,
COUNT(c.Number) AS Total,
ParentNumber AS Parent,
COUNT(c.Number)/q.Total AS Percentage
FROM tblChild AS c INNER JOIN tblParent AS q ON c.ParentNumber = q.Number
GROUP BY ParentNumber
This throws: You tried to execute a query ... 'Count(1)/q.Total' as part of an aggregate function
. Adding it to the group-by statement throws Cannot have aggregate function in GROUP BY
...
回答1:
Your subquery has no where clause and thus counts all records, but you can do it without subquery
SELECT
"Criterion = 1" AS CritDesc,
SUM(IIf(Criterion = 1, 1, 0)) AS NumCrit,
COUNT(*) AS TotalNum,
SUM(IIf(Criterion = 1, 1, 0)) / COUNT(*) AS Percentage,
ParentNumber AS Parent
FROM
tblChild
GROUP BY
ParentNumber;
Note: I dropped the WHERE-clause. Instead I am counting the records fulfilling the criterion by summing up 1
for Criterion = 1
and 0
otherwise. This allows me to get the total number per ParentNumber
at the same time with Count(*)
.
UPDATE
You might want to get results for parents having no children as well. In that case you can use an outer join
SELECT
"Criterion = 1" AS CritDesc,
SUM(IIf(C.Criterion = 1, 1, 0)) AS NumCrit,
COUNT(C.Number) AS TotalNumOfChildren,
SUM(IIf(C.Criterion = 1, 1, 0)) / COUNT(*) AS Percentage,
P.Number AS Parent
FROM
tblChild AS C
LEFT JOIN tblParent AS P
ON C.ParentNumber = P.Number
GROUP BY
P.Number;
Note that I get the total number of children with Count(C.Number)
as Count(*)
would count records with no children as well and yield 1
in that case. In the percentage calculation, however, I divide by Count(*)
in order to avoid a division by zero. The result will still be correct in that case, since the sum of records with Criterion = 1
will be zero.
回答2:
If you are working within MS Access, you can divide by a DCount of parents.
Total/DCount("Parent","Table","Parent=" & Parent)
You could also create a count query
SELECT Parent, Count(Parent) FROM Table GROUP BY Parent
And then add both queries to the design grid joining them on Parent.
来源:https://stackoverflow.com/questions/11329936/calculate-percentages-in-query-access-sql