Calculating a Percentage of Correct Answers
Writing a query that calculates percentages from a bit column might prove to be more difficult than you think. Itzik Ben-Gan describes an efficient method.
October 31, 2002
I wrote the statement that Listing 3 shows, which contains the results of participant answers to quiz questions in a bit column named correct. In Listing 3's sample data, 0.75 (75 percent) of participant A's answers and 0.50 (50 percent) of B's answers are correct. How can I write a query that calculates what percentage of each participant's answers is correct?
The value 1 represents a correct answer and 0 an incorrect answer, so the percentage of correct answers is actually the same as the average of the values in the correct column. Therefore, you ought to be able to average the column values. However, when you try to run the following query to average the values for each participant ID:
SELECT participantid, AVG(correct) AS avg_correctFROM QuizResultsGROUP BY participantid
you receive an error message saying that an aggregate function can't take a bit data type as an argument. In attempting to avoid the error, you might try to convert the bit value to an integer data type, as the following code demonstrates:
SELECT participantid, AVG(CAST(correct AS int)) AS avg_correctFROM QuizResultsGROUP BY participantid
Although the query doesn't generate an error, it results in another problem. Both A and B return 0 because the AVG() function returns a value with the same data type as its argument, which in this case is an integer. SQL Server truncates integers, so when you convert the numeric values 0.75 and 0.50 into integers, it truncates them to 0. For example, when you run the following code:
SELECT CAST(0.75 AS int)
the result is 0. A workable solution is to convert the correct column to a numeric data type either explicitly or implicitly. The following modified query shows an implicit conversion caused by multiplying 1. (read "one dot") by the correct column:
SELECT participantid, CAST(AVG(1. * correct) AS numeric(3, 2)) AS avg_correctFROM QuizResultsGROUP BY participantid
And you should receive the desired results.
About the Author
You May Also Like