Question

J'ai deux tables, une avec toutes mes branches, et une avec toutes mes ventes. Le tableau des ventes contient également un code représentant commercial, un ID de succursale, un mois et un an.

J'ai besoin d'une requête qui renverra la somme d'un chiffre d'affaires de rep spécifique pour une année, regroupés par branche et par mois, et la requête doit retourner 0 s'il n'y a pas eu de ventes dans une branche pour ce mois. J'ai ce qui suit, qui ne retourne pas 0 s'il n'y a pas de vente:

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
Était-ce utile?

La solution

Vous devrez ajouter les données « manquantes » pour être en mesure de le joindre.

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

Autres conseils

Vous devez faire un LEFT JOIN aux ventes, de façon à revenir même les représentants qui n'ont pas de dossiers dans le tableau des ventes.

Si votre requête retourne NULL, vous pouvez utiliser l'une des méthodes coalescents: COALESCE(SUM(...), 0) retourne la première valeur non NULL dans la liste ...

Vous devez utiliser une jointure gauche et un isnull pour obtenir le droit à la somme:

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

Vous avez encore besoin de faire un peu plus de travail avec elle pour obtenir les mois montrant aussi si un vendeur ne vend pas dans un mois donné.

J'ai changé la jointure de l'intérieur vers extérieur et ajouté a quitté la fonction ISNULL pour les branches sans ventes.

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top