tags:

views:

50

answers:

2

Hi, I have a feeling I am making some sort of foolish mistake here, however I am trying to do a query over two tables. One table contains the value I want to aggregate over, in this case I have called if the StoreCharge table. The other table contains the values I want to count.

SELECT  StoreCharge.StoreId,
        COUNT(DISTINCT(ISNULL(WholesalerInvoice.WholesalerId,0))) AS Invoices
FROM    StoreCharge 
            LEFT OUTER JOIN
            WholesalerInvoice ON StoreCharge.StoreId = WholesalerInvoice.StoreId
WHERE   StoreCharge.CompanyId = 2
AND         WholesalerInvoice.StoreInvoiceId IS NULL
AND         DATEDIFF(day,WholesalerInvoice.InvoiceDate,'20100627') > =0
AND     DATEDIFF(day,dateadd(day,-7,'20100627'),WholesalerInvoice.InvoiceDate) > 0
GROUP BY    StoreCharge.StoreId

My problem is that if there are rows in the counting table that match the WHERE clause, the query works ok. However When no rows match the criteria nothing is returned instead of a list of the values in StoreCharge with a count of 0.

+1  A: 

Based on the query in the example, you don't actually use what you join in. Unless there is more to the query a Subquery would produce the desired result.

SELECT  StoreCharge.StoreId,
        (SELECT COUNT(0) FROM WholesalerInvoice WHERE WholesalerInvoice.StoreId = StoreCharge.StoreId
        AND DATEDIFF(day,WholesalerInvoice.InvoiceDate,'20100627') > =0
        AND DATEDIFF(day,dateadd(day,-7,'20100627'),WholesalerInvoice.InvoiceDate) > 0) [Invoices]
FROM    StoreCharge 
WHERE   StoreCharge.CompanyId = 2
Don
I think I am going to have to go down this route. Luckily the process will only be run once or twice a week so a little bit of a performance hit is acceptable. Thanks for this.
Dom
Ah have managed to get @ChrisBednarskis solution working. I find that solution more preferable as I don't need to do subquery then which will make for better performance and it fits in better with the rest of the data I am selecting (which was omitted as it wasn't relevant). Many thanks :-)
Dom
+1  A: 

WHERE is evaluated after the LEFT OUTER JOIN

Try moving your WHERE filter related to WholesalerInvoice into the OUTER JOIN

SELECT  StoreCharge.StoreId, 
        COUNT(DISTINCT(ISNULL(WholesalerInvoice.WholesalerId,0))) AS Invoices 
FROM    StoreCharge  
    LEFT OUTER JOIN 
    WholesalerInvoice ON StoreCharge.StoreId = WholesalerInvoice.StoreId 
AND DATEDIFF(day,WholesalerInvoice.InvoiceDate,'20100627') > =0 
AND DATEDIFF(day,dateadd(day,-7,'20100627'),WholesalerInvoice.InvoiceDate) > 0 

WHERE   StoreCharge.CompanyId = 2 
GROUP BY    StoreCharge.StoreId

This will filter the required WholesalerInvoice records out and leave the StoreCharge table intact.

Chris Bednarski
Ah this query returns the data but doesn't seem to taken into account the and clauses now. It returns values that should be omitted.
Dom
You're right about the join -- I had missed that StoreId and CompanyId were different columns. I assumed we were only looking at a single store. Don't you need to put the ISNULL outside COUNT, though: `ISNULL(COUNT(DISTINCT(WholesalerInvoice.WholesalerId)),0)`? Otherwise, it will be adding in one if there is a NULL WholesalerId in the join.
tvanfosson
ah yes you are probably correct. Thanks.
Dom