Domanda

Ho due tavoli, uno con tutti i miei rami, e uno con tutte le mie vendite. La tabella di vendita contiene anche un ID Sales Rep, un ID Branch, un mese e un anno.

Ho bisogno di una query che restituirà la somma delle vendite di un rappresentante specifico per un anno, raggruppati per ramo e il mese, e la query deve restituire 0 se non v'è stata nessuna vendita in un ramo per quel mese. Ho il seguente, che non restituisce 0 se non ci sono le vendite:

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
È stato utile?

Soluzione

Sarà necessario aggiungere i dati "mancanti" per essere in grado di farne parte.

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

Altri suggerimenti

È necessario fare un LEFT JOIN alle vendite, in modo da tornare anche i rappresentanti che non hanno tutti i record nella tabella vendite.

Se la query sta tornando NULL, è possibile utilizzare uno dei metodi coalescenza: COALESCE(SUM(...), 0) restituirà il primo valore non NULL nella lista ...

È necessario utilizzare un join sinistro ed un IsNull per ottenere la somma giusta:

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

Hai ancora bisogno di fare un po 'più di lavoro con esso per ottenere i mesi mostrando anche se un venditore non ha le vendite in un determinato mese.

Ho cambiato il join da interno a sinistra esterno e aggiunto la funzione ISNULL per rami con nessuna vendita.

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top