Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL - Returning all rows even if count is zero for item

I am performing a count based on a date range. Currently the query does return the correct result but I require additional information. In it's current form, the query shows the item with the correct count. However I need all items to be shown, even if their count is zero for the date range specified.

Here is the SQL code:

INSERT INTO @CreationCount (BaselineID, Name)

SELECT distinct [BaselineID],[Name] 
FROM [Baseline_INFO] 

DECLARE @ReqType TABLE (Type nvarchar(128))
INSERT INTO @ReqType (Type)
SELECT DISTINCT Tree.Type as 'Requirement Type'
FROM [TREE]
INNER JOIN [Project_INFO]  ON [Project_INFO].[ProjectID]=[Tree].[Project_ID] 
INNER JOIN [Baseline_INFO] ON [Baseline_INFO].[BaselineID]=[Tree].[Baseline_ID]
WHERE [Project_INFO].[Name] = 'Address Book' AND [Baseline_INFO].[Name] = 'Current
Baseline' 
Group By Tree.Type

SELECT Tree.Type as 'Requirement Type', COUNT(Tree.Type) as 'Number in Creation Range' 
FROM [Tree] 
INNER JOIN @ReqType As RT on RT.Type = Tree.Type
INNER JOIN [Project_INFO]  ON [Project_INFO].[ProjectID]=[Tree].[Project_ID] 
INNER JOIN @CreationCount AS CCount ON CCount.BaselineID=Tree.Baseline_ID 
WHERE [Project_INFO].[Name] = 'Address Book' AND CCount.Name = 'Current Baseline' 
AND [Tree].[creationDate] >= ('2010-01-01') and [Tree].[creationDate] < ('2020-01-01') 
GROUP BY tree.Type

When I execute this query I get the following result:

https://dl.dropbox.com/u/17234826/SQLresult.png

This result is correct however I need all requirement types to be list, even if there are no requirements in the creation range, i.e.

https://dl.dropbox.com/u/17234826/SQLresult1.png

I have tried using various joins, IFNULL and ISNULL but I haven't got anything to work.

If someone could point me in the right direction I'd appreciate it.

like image 524
user1454112 Avatar asked Oct 05 '12 13:10

user1454112


People also ask

How do you show zero as count if there is no record in database?

you can use ISNULL or COALESCE:both are same with a small difference. ISNULL(param1,param2): can contains only 2 parameter, and there are no condition of having it's value.

Does count Return 0 SQL?

The SQL COUNT() function returns the number of rows in a table satisfying the criteria specified in the WHERE clause. It sets the number of rows or non NULL column values. COUNT() returns 0 if there were no matching rows.

Does count () Count zero?

The result is a BIGINT value. It is an aggregate function, and so can be used with the GROUP BY clause. COUNT(*) counts the total number of rows in a table. COUNT() returns 0 if there were no matching rows.

What does count 0 do in SQL?

COUNT(*) will count the number of rows, while COUNT(expression) will count non-null values in expression and COUNT(column) will count all non-null values in column. Since both 0 and 1 are non-null values, COUNT(0)=COUNT(1) and they both will be equivalent to the number of rows COUNT(*) .


2 Answers

Modify the second query

SELECT Tree.Type as 'Requirement Type',
       COUNT(CASE WHEN [Tree].[creationDate] >= ('2010-01-01') and [Tree].[creationDate] < ('2020-01-01') THEN Tree.Type END) AS 'Number in Creation Range'
FROM [Tree] 
INNER JOIN @ReqType As RT on RT.Type = Tree.Type
INNER JOIN [Project_INFO]  ON [Project_INFO].[ProjectID]=[Tree].[Project_ID] 
INNER JOIN @CreationCount AS CCount ON CCount.BaselineID=Tree.Baseline_ID 
WHERE [Project_INFO].[Name] = 'Address Book' AND CCount.Name = 'Current Baseline' 
GROUP BY tree.Type
like image 62
Aleksandr Fedorenko Avatar answered Oct 26 '22 23:10

Aleksandr Fedorenko


Generally speaking, to get records with counts of 0, you need an outer join of some sort so you count the rows that have no match. You can even use a cross-join of all the options you want counts for. Alternatively, I often implement this type of count by using a correlated subquery. Here are a couple of general examples:

-- Get count using left join
select c.customer_id,
    count(o.order_id) as num
from customers c
    left join orders o on c.customer_id = o.customer_id
group by c.customer_id

-- Get count using correlated subquery
select c.customer_id,
    (select count(*) from orders where customer_id = c.customer_id) as Num
from customers c

Another possibility, if you've got a working query, is to hack together something like this:

-- Create a cte of the original query that we will use multiple times
;WITH cte as (
    SELECT Tree.Type as 'Requirement Type'
        , COUNT(Tree.Type) as 'Number in Creation Range' 
    FROM [Tree] 
        INNER JOIN @ReqType As RT on RT.Type = Tree.Type
        INNER JOIN [Project_INFO]  ON [Project_INFO].[ProjectID]=[Tree].[Project_ID] 
        INNER JOIN @CreationCount AS CCount ON CCount.BaselineID=Tree.Baseline_ID 
    WHERE [Project_INFO].[Name] = 'Address Book' AND CCount.Name = 'Current Baseline' 
        AND [Tree].[creationDate] >= ('2010-01-01') and [Tree].[creationDate] < ('2020-01-01') 
    GROUP BY tree.Type
)
-- Grab the counts of records with matches
select *
from cte
-- Grab the zero counts (records not in the original query)
union all
select Tree.Type, 0
from [Tree]
where Tree.Type not in (
    select Tree.Type
    from cte
)
like image 45
Tim Lehner Avatar answered Oct 26 '22 23:10

Tim Lehner