Select Count(Distinct Value) returns 1
I'm designing a query in SSMS 2005 which looks s开发者_如何学JAVAomething like this:
SELECT COUNT(DISTINCT ColumnName) FROM Table WHERE ColumnName IS NOT NULL
When I run the query with COUNT() it returns the value 1. When I run it without COUNT(), SSMS reports the correct value eg 212 records.
The column in question is of datatype numeric(16, 0).
For those who might ask, the query in full is:
SELECT COUNT(DISTINCT O_ID) FROM vEmployers
INNER JOIN vEnrolment ON O_ID = E_EnrolmentEmployer
WHERE E_START >= '01-AUG-2008' AND E_START < '01-AUG-2009'
AND O_ID IS NOT NULL AND O_ID IN (
SELECT O_ID FROM vEmployers
INNER JOIN vEnrolment ON O_ID = E_EnrolmentEmployer
WHERE E_Start < '01-AUG-2008' and E_Start >= '01-AUG-2007'
)
This query basically gives a repeat business figure between two 12month periods.
So I'm wondering why "COUNT(DISTINCT ColumnName)" is returning 1 when "ColumnName IS NOT NULL" has been specified?
Here is a sample of the data when SELECT TOP 10 DISTINCT ColumnName FROM... etc is run:
1346116
1346131
1346425
1346923
1349935
1350115
1350153
2594787
2821944
2879631
The use of the numeric(16, 0) made me suspect that it was data type related. Add a CAST in the COUNT clause to cast it to an INT type:
Count(Distinct Cast(O_ID as Int))
I'm guessing it's because all rows returned share the same value for O_ID
. You can do a COUNT(*)
or COUNT()
on a key that is unique to each row to get the row count.
Could you please run these queries:
SELECT COUNT(DISTINCT O_ID)
FROM vEmployers
INNER JOIN
vEnrolment
ON O_ID = E_EnrolmentEmployer
WHERE E_START >= '01-AUG-2008' AND
E_START < '01-AUG-2009'
AND O_ID IN
(
SELECT O_ID
FROM vEmployers
INNER JOIN
vEnrolment
ON O_ID = E_EnrolmentEmployer
WHERE E_Start < '01-AUG-2008'
AND E_Start >= '01-AUG-2007'
)
and
SELECT DISTINCT TOP 5 O_ID
FROM vEmployers
INNER JOIN
vEnrolment
ON O_ID = E_EnrolmentEmployer
WHERE E_START >= '01-AUG-2008' AND
E_START < '01-AUG-2009'
AND O_ID IN
(
SELECT O_ID
FROM vEmployers
INNER JOIN
vEnrolment
ON O_ID = E_EnrolmentEmployer
WHERE E_Start < '01-AUG-2008'
AND E_Start >= '01-AUG-2007'
)
ORDER BY
O_ID
verbatim, without changing anything?
SELECT
COUNT(*)
FROM vEmployers
INNER JOIN vEnrolment ON O_ID = E_EnrolmentEmployer
WHERE
E_START >= '01-AUG-2008'
AND E_START < '01-AUG-2009'
AND O_ID IS NOT NULL AND O_ID IN (
SELECT O_ID FROM vEmployers
INNER JOIN vEnrolment ON O_ID = E_EnrolmentEmployer
WHERE E_Start < '01-AUG-2008' and E_Start >= '01-AUG-2007'
)
GROUP BY
O_Id
Remove the DISTINCT and you'll get a count on all rows.
精彩评论