2009-07-08 6 views
3

Ich habe zwei Tabellen, eine mit allen meinen Filialen und eine mit allen meinen Verkäufen. Die Verkaufstabelle enthält außerdem eine Vertriebsrepräsentanten-ID, eine Filial-ID, einen Monat und ein Jahr.T-SQL, Nullsumme für keine Übereinstimmung bei Join

Ich brauche eine Abfrage, die die Summe der Verkäufe eines bestimmten Repräsentanten für ein Jahr zurückgibt, gruppiert nach Zweig und Monat, und die Abfrage muss 0 zurückgeben, wenn in einem Zweig für diesen Monat keine Verkäufe stattgefunden haben. Ich habe die folgenden, die nicht 0 zurück, wenn es keine Verkäufe sind:

SELECT 
    s.Month, 
    b.BranchName, 
    SUM(s.InvoiceAmount) AS 'Sales' 
FROM 
    Branch b 
INNER JOIN 
    Sales s ON s.BranchID = b.BranchID 
WHERE 
    s.Year = 2008 
AND 
    s.SalesRepID= 11 
GROUP BY 
    s.Month, 
    b.BranchName 
ORDER BY 
    s.Month, 
    b.BranchName 
+0

Vermissen Sie am Montag aus der SELECT-Liste? – pjp

+0

Mein Fehler, ja die am MONTH ist in der SELECT – staterium

+0

(korrigiert in OP) – staterium

Antwort

4

Sie müssen die "fehlenden" Daten hinzufügen, um beitreten zu können.

SELECT 
    b.BranchName, 
    SUM(ISNULL(s.InvoiceAmount, 0)) AS 'Sales', 
    s.Month 
FROM 
    Branch b 
    LEFT OUTER JOIN (
      SELECT 
     b.BranchID AS BranchID 
     , s.SalesRepID AS SalesRepID 
     , Months.Month AS Month 
     , Years.Year AS Year 
     , 0 AS InvoiceAmount 
     FROM 
      Sales s 
      CROSS JOIN (
      SELECT 1 AS Month 
      UNION ALL SELECT 2 
      UNION ALL SELECT 3 
      UNION ALL SELECT 4 
      UNION ALL SELECT 5 
      UNION ALL SELECT 6 
      UNION ALL SELECT 7 
      UNION ALL SELECT 8 
      UNION ALL SELECT 9 
      UNION ALL SELECT 10 
      UNION ALL SELECT 11 
      UNION ALL SELECT 12 
      ) Months 
      CROSS JOIN (
      SELECT 2007 AS Year 
      UNION ALL SELECT 2008 
      UNION ALL SELECT 2009 
      ) Years 
      CROSS JOIN Branch b 
     UNION ALL SELECT 
     s.BranchID AS BranchID 
     , s.SalesRepID AS SalesRepID 
     , s.Month AS Month 
     , s.Year AS Year 
     , s.InvoiceAmount AS InvoiceAmount 
     FROM Sales s  
    )s ON s.BranchID = b.BranchID  
WHERE 
    s.Year = 2008 
    AND s.SalesRepID= 11 
GROUP BY 
    s.Month, 
    b.BranchName 
ORDER BY 
    b.BranchName, 
    s.Month 
+0

Ich war im Begriff, etwas Ähnliches zu posten – pjp

+1

froh zu hören, ich bin nicht allein in der Art, wie ich die Frage interpretierte. Alle anderen Antworten scheinen sich auf NULL-Werte in InvoiceAmount zu konzentrieren. Ich bezweifle, dass das OP gemeint ist. –

+0

Danke Lieven, das funktioniert (so). Ich bekomme jetzt 0 Werte für Monate, in denen der Repräsentant keine Verkäufe in diesem Zweig hatte, aber die Abfrage als Ganzes gibt nur Zweige zurück, wo der Repräsentant zu irgendeinem Zeitpunkt im Jahr Verkäufe hatte. – staterium

2

Sie erhalten eine LEFT JOIN Verkäufe tun müssen, so wie auch die Wiederholungen zurückzugeben, die haben noch keine Einträge in der Verkaufstabelle.

+0

Left Join sollte diese Zweige ohne Verkäufe in der endgültigen Abfrage erscheinen und das Aggregat wird dann für sie zurückgeben. – Spence

+0

-1 Es gibt eine Where-Klausel in s.SalesRepId und daher wäre ein linker äußerer Join auf Sales sinnlos. – pjp

1

Wenn Ihre Abfrage NULL zurückgibt, können Sie eine der koaleszierenden Methoden verwenden: COALESCE(SUM(...), 0) werden den ersten nicht-NULL-Wert in der Liste zurück ...

+0

Sollte die Koaleszenz nicht innerhalb der Summe liegen? Oder die Summe kann über NULL-Werte summieren. Ich nehme an, dass dies eine Warnung im SQL-Server auslöst. – pjp

+0

Warnung: Nullwert wird durch ein Aggregat oder eine andere SET-Operation eliminiert. (1 Zeile (n) betroffen) – pjp

0

Ich änderte die von innerer Verknüpfung zu dem äußeren linken und hinzugefügt die ISNULL-Funktion für Filialen ohne Verkauf.

SELECT 

    b.BranchName, 
    s.Month, 
    SUM(ISNULL(s.InvoiceAmount,0)) AS 'Sales' 
FROM 
    Branch b 
LEFT JOIN 
    Sales s ON s.BranchID = b.BranchID 
WHERE 
    s.Year = 2008 
AND 
    s.SalesRepID= 11 
GROUP BY 
    s.Month, 
    b.BranchName 
ORDER BY 
    s.Month, 
    b.BranchName 
+0

Die Frage fragt nach Verkäufen nach Monat, auch wenn in einem bestimmten Monat keine Verkäufe getätigt werden. Diese Abfrage gibt Ergebnisse für das ganze Jahr zurück. – pjp

+0

Das hat mein Ergebnis nicht verändert. – staterium

0

Sie müssen links verwenden verbinden und eine isnull die Summe erhalten rechts:

SELECT b.BranchName 
, SUM(isnull(s.InvoiceAmount, 0)) AS 'Sales' 
FROM  Branch b 
LEFT JOIN Sales s ON s.BranchID = b.BranchID 
GROUP BY  s.Month, b.BranchName 
ORDER BY  s.Month, b.BranchName 

Sie müssen noch mit ihm etwas mehr Arbeit tun, um die Monate zu bekommen zeigt, wenn ein Verkäufer hat keine Verkäufe in einem bestimmten Monat.

Verwandte Themen