Как показать наборы результатов, которые являются нулевыми из функции суммы - PullRequest
1 голос
/ 26 августа 2011

Я использую функцию sum для суммирования всех счетов для клиента: СУММА (отличается (T1. [GTotal])) как InvoiceTotal

Я знаю, что у меня есть клиенты, у которых есть счет, но общая сумма счета равна 0. Функция не будет показывать эти записи.

Как я могу убедиться, что запрос отображает их?


SELECT DISTINCT
    T2.CardCode as CustomerId, 
    T2.CntctPrsn as ContactPerson, 
    T2.Phone1 as Phone, 
    T4.GroupName as CustomerType, 
    T5.descript as Territory,
    MAX(CASE WHEN T3.AdresType = 'B' THEN T3.Address ELSE NULL END) AS BillToCustomerName,  
    MAX(CASE WHEN T3.AdresType = 'B' THEN T3.Street ELSE NULL END) AS BillToAddress1,
    MAX(CASE WHEN T3.AdresType = 'B' THEN T3.Block ELSE NULL END) AS BillToAddress2,
    MAX(CASE WHEN T3.AdresType = 'B' THEN T3.City ELSE NULL END) AS BillToCity,
    MAX(CASE WHEN T3.AdresType = 'B' THEN T3.State ELSE NULL END) AS BillToState,
    MAX(CASE WHEN T3.AdresType = 'B' THEN T3.ZipCode ELSE NULL END) AS BillToZipCode,
    MAX(CASE WHEN T3.AdresType = 'B' THEN T3.County ELSE NULL END) AS BillToCounty,
    MAX(CASE WHEN T3.AdresType = 'B' THEN T3.Country ELSE NULL END) AS BillToCountry,
    MAX(CASE WHEN T3.AdresType = 'S' THEN T3.Address ELSE NULL END) AS ShipToCustomerName,  
    MAX(CASE WHEN T3.AdresType = 'S' THEN T3.Street ELSE NULL END) AS ShipToAddress1,
    MAX(CASE WHEN T3.AdresType = 'S' THEN T3.Block ELSE NULL END) AS ShipToAddress2,
    MAX(CASE WHEN T3.AdresType = 'S' THEN T3.City ELSE NULL END) AS ShipToCity,
    MAX(CASE WHEN T3.AdresType = 'S' THEN T3.State ELSE NULL END) AS ShipToState,
    MAX(CASE WHEN T3.AdresType = 'S' THEN T3.ZipCode ELSE NULL END) AS ShipToZipCode,
    MAX(CASE WHEN T3.AdresType = 'S' THEN T3.County ELSE NULL END) AS ShipToCounty,
    MAX(CASE WHEN T3.AdresType = 'S' THEN T3.Country ELSE NULL END) AS ShipToCountry,
    COUNT(distinct(T0.[DocNum])) as Invoices,
    SUM(distinct(T1.[GTotal])) as InvoiceTotal 
FROM asap.dbo.OINV T0  
    INNER JOIN asap.dbo.INV1 T1 ON T0.DocEntry = T1.DocEntry 
    INNER JOIN asap.dbo.OCRD T2 ON T0.CardCode = T2.CardCode 
    INNER JOIN asap.dbo.CRD1 T3 ON T2.CardCode = T3.CardCode
    INNER JOIN asap.dbo.OCRG T4 ON T2.GroupCode = T4.GroupCode 
    INNER JOIN asap.dbo.OTER T5 ON T2.Territory = T5.territryID 
WHERE T0.DocDate >= '2008-01-01 00:00:00.000' AND 
      T0.DocDate <= '2011-12-31 00:00:00.000' AND 
      T4.[GroupName] ='WholeSale' AND   
      T5.[descript] = 'Region 04' 
GROUP BY T2.[CardCode], 
      T2.[CntctPrsn], 
      T2.[Phone1], 
      T4.[GroupName], 
      T5.[descript]

Я получаю все счета с общей суммой, однако, если есть счета, у которых нет $, они не отображаются в результатах. Отчет будет использоваться для изучения существующей клиентской базы для конкретной территории и позволит продавцам ориентироваться на клиентов, которые не покупали в течение длительного времени или имеют низкие продажи. Из соображений конфиденциальности приведена сокращенная версия результатов:

Customer  Customer Type  Territory  Total Invoices  Total $ Spent
--------  -------------  ---------  --------------  -------------
C100177   Wholesale      Region 04  77              15813.1
C100208   Wholesale      Region 04  2               540
C100209   Wholesale      Region 04  5               809
C100213   Wholesale      Region 04  2               344.7
C100215   Wholesale      Region 04  5               1249.8

Вот записи, которые отсутствуют:

Customer  Customer Type  Territory  Total Invoices  Total $ Spent
--------  -------------  ---------  --------------  -------------
C110885   Wholesale      Region 04  1               0
C123218   Wholesale      Region 04  1               0
C128694   Wholesale      Region 04  1               0
C158528   Wholesale      Region 04  1               0
C168646   Wholesale      Region 04  1               0

Ответы [ 3 ]

2 голосов
/ 26 августа 2011

Похоже, что у некоторых клиентов нет строк в таблице счетов?Вы должны использовать внешнее соединение.

SELECT
  c.CustomerId
 ,c.CustomerName
 ,SUM(COALESCE(i.GTotal, 0)) AS InvoiceTotal
FROM Customers c
  LEFT OUTER JOIN Invoices i ON c.CustomerId = i.CustomerId
GROUP BY c.CustomerId, c.CustomerName
ORDER BY c.CustomerName
0 голосов
/ 27 августа 2011

Я согласен с Робом Беком в том, что ваше решение должно использовать где-то хотя бы одно внешнее соединение. На мой взгляд, таблицы для внешнего объединения - это OINV и OCRD, но вам также следует переместить некоторые условия из WHERE в соответствующее предложение ON, чтобы внешние объединения имели необходимый эффект.

Если быть более точным, я бы, вероятно, переставил соединения и условия, подобные этому:

…
FROM asap.dbo.OCRD T2  
    LEFT JOIN asap.dbo.OINV T0 ON T0.CardCode = T2.CardCode AND 
        T0.DocDate >= '2008-01-01 00:00:00.000' AND 
        T0.DocDate <= '2011-12-31 00:00:00.000' 
    LEFT JOIN asap.dbo.INV1 T1 ON T0.DocEntry = T1.DocEntry 
    INNER JOIN asap.dbo.CRD1 T3 ON T2.CardCode = T3.CardCode
    INNER JOIN asap.dbo.OCRG T4 ON T2.GroupCode = T4.GroupCode 
    INNER JOIN asap.dbo.OTER T5 ON T2.Territory = T5.TerritoryID 
WHERE T4.[GroupName] ='WholeSale' AND   
      T5.[descript] = 'Region 04' 
…

Одна вещь, с которой я не согласен с Робом, это то, как применить COALESCE, чтобы исключить возможный NULL-результат SUM. На мой взгляд, COALESCE следует применять к результату SUM, а не к его аргументу.

0 голосов
/ 26 августа 2011

Сначала запустите этот запрос

select count(*)
FROM asap.dbo.OINV T0       

Затем добавьте каждое условие соединения отдельно и снова выполните запрос

INNER JOIN asap.dbo.INV1 T1 ON T0.DocEntry = T1.DocEntry      
INNER JOIN asap.dbo.OCRD T2 ON T0.CardCode = T2.CardCode      
INNER JOIN asap.dbo.CRD1 T3 ON T2.CardCode = T3.CardCode     
INNER JOIN asap.dbo.OCRG T4 ON T2.GroupCode = T4.GroupCode      
INNER JOIN asap.dbo.OTER T5 ON T2.Territory = T5.territryID  

Одно из условий соединения снизит счет. Например, если T0.DocEntry пуст для счетов без сумм, то первое СОЕДИНЕНИЕ снизит ваш счет ...

Как только вы узнаете, какая таблица вызывает проблему, ее будет легче исправить

...