-3

I'm trying to make this query show 0 in the "nb" field when there are no record found for a specific date. Right now the output is 0 row, unless the date i specify exists in the "Commande" table.

SELECT      
  isnull(COUNT(*), 0) as nb, 
  CONVERT(date, c.Date_commande) as Date_commande, 
  f.Code_fournis
FROM        Commande c
LEFT JOIN   Fournisseur f
ON          c.Code_fournis = f.Code_fournis
WHERE       f.Code_fournis = 'XNZ'
AND         Convert(date, c.Date_commande) = '2015-10-28'
GROUP BY    CONVERT(date, c.Date_commande), f.Code_fournis
ORDER BY    c.date_commande desc
Chris Moutray
  • 18,029
  • 7
  • 45
  • 66
Sibanak
  • 25
  • 7
  • There isn't a NULL, there is no row at all. That is because your query doesn't have any rows to return because of the where clause. There a number ways you can handle this. You could use an EXISTS check and return hard coded values NOT EXISTS. – Sean Lange Oct 29 '15 at 15:16
  • Just a comment, your LEFT JOIN executes as a regular inner join... Move f.Code_fournis = 'XNZ' from WHERE to ON to get true LEFT JOIN behavior. – jarlh Oct 29 '15 at 15:16

3 Answers3

0

The problem is you can't count what isn't there. You need create a table allDates for all the dates. 100 years mean 36,500 rows so is a small table. Use this one as example

How can I generate a temporary table filled with dates in SQL Server 2000?

Then

SELECT      
  isnull(COUNT(*), 0) as nb, 
  CONVERT(date, AD.date) as Date_commande, 
  f.Code_fournis
FROM        
            allDates AD
LEFT JOIN   Commande c
       ON   AD.date = CONVERT(date, c.Date_commande)
LEFT JOIN   Fournisseur f
       ON   c.Code_fournis = f.Code_fournis
WHERE       f.Code_fournis = 'XNZ'
AND         Convert(date, c.Date_commande) = '2015-10-28'
GROUP BY    CONVERT(date, AD.date), f.Code_fournis
ORDER BY    AD.date desc
Community
  • 1
  • 1
Juan Carlos Oropeza
  • 47,252
  • 12
  • 78
  • 118
  • I created a table with dates and I tried your query and it returns no row – Sibanak Oct 29 '15 at 16:10
  • well I dont have your schema so I cant test it. Just add one table each time. Maybe is the join condition on `convert(date)`... Or prepare a sample schema in http://sqlfiddle.com/ – Juan Carlos Oropeza Oct 29 '15 at 16:13
-1

Because '2015-10-28' does not exists in Commande, you need to create an row for it in a dummy table:

SELECT      
  SUM(case when c.Date_commande is null then 0 else 1 end) as nb, 
  d.Date_commande as Date_commande, 
  f.Code_fournis
FROM (values(cast('20150101' as date), 'XNZ') as d(Date_commande, Code_fournis)      
LEFT JOIN Commande c on Cast(c.Date_commande as date) = d.Date_commande
LEFT JOIN   Fournisseur f
ON          c.Code_fournis = f.Code_fournis and f.Code_fournis = d.Code_fournis
GROUP BY    d.Date_commande, f.Code_fournis
ORDER BY    d.Date_commande desc

This would work as well:

SELECT isnull(COUNT(*), 0) as nb, 
    CONVERT(date, c.Date_commande) as Date_commande, 
    f.Code_fournis
From your query
Union All
Select 0, '20150101', 'XNZ'
Where not exist (
    select 1 
    From Commande c
    LEFT JOIN   Fournisseur f
    ON c.Code_fournis = f.Code_fournis and  = d.Code_fournis
    Where f.Code_fournis = 'XNZ' 
        AND Convert(date, c.Date_commande) = '20150101'
 )
Julien Vavasseur
  • 3,854
  • 1
  • 20
  • 29
-1

Even though this is old and has a few downvotes, I recently solved my problem. I had to generate a table with dates.

SELECT      SUM(CONVERT(int, case(vtl.oeil) WHEN RTRIM('I') THEN 2 ELSE 1 END)) as nb, 
            CONVERT(date, c.Date_commande) as Date_commande,
            RTRIM(f.Code_fournis) AS Code_fournis
FROM        Commande c
LEFT JOIN   Fournisseur f
ON          c.Code_fournis = f.Code_fournis
WHERE       c.Code_fournis = 'XNZ'
AND         Convert(date, c.Date_commande)
BETWEEN     '2015-11-30'
AND         '2015-12-04'
GROUP BY    CONVERT(date, c.Date_commande), f.Code_fournis
UNION ALL
SELECT      '0', date, 'XNZ'
FROM        allDates
WHERE       date    
BETWEEN     '2015-11-30'
AND         '2015-12-04'
AND date NOT IN (
        SELECT      convert(date, c.Date_commande) as date
        FROM        allDates ad 
        INNER JOIN  Commande c 
        ON          ad.date = convert(date, c.Date_commande) 
        WHERE       c.Code_fournis = 'XNZ'
        and         convert(date, c.Date_commande) 
        BETWEEN     '2015-11-30'
        AND         '2015-12-04'
)
ORDER BY    c.date_commande asc

It's a bit different then what I asked for but hopefully it can help someone.

Sibanak
  • 25
  • 7