MS SQL - JOIN显示没有数据的月份

时间:2018-03-12 09:11:09

标签: sql sql-server

我遇到了 SQL JOINS 的新问题。

这是我的情景。

我有一份报告,我需要显示特定客户的销售业绩。 该报告显示了每月的销售业绩。

请查看我的结果集:

AFP035

这是客户AFP035的销售报告。正如您所看到的,有几个月没有显示出来。我需要包括那些没有数据的月份(NULL)。

这是我尝试过的。我创建了一个月份表来维持月份。

table months

然后我做了 LEFT JOIN 。似乎很奇怪,因为它没有显示出所需的结果。根据我的理解 LEFT JOIN 应该显示NULL值。我错了。

请参阅我的问题:

select  CustNm as company,
        Cust as customer,
        Cust as custCode,
        Mon,
        case
        when Mon = 1 THEN 'January'
        when Mon = 2 THEN 'February'
        when Mon = 3 THEN 'March'
        when Mon = 4 THEN 'April'
        when Mon = 5 THEN 'May'
        when Mon = 6 THEN 'June'
        when Mon = 7 THEN 'July'
        when Mon = 8 THEN 'August'
        when Mon = 9 THEN 'September'
        when Mon = 10 THEN 'October'
        when Mon = 11 THEN 'November'
        when Mon = 12 THEN 'December'
        end as 'month',
        Yr as 'year',
        Mon as monthCheck,

        case
        when NetSales IS NULL THEN 0
        else NetSales
        end as netSales,

        case
        when PrvYrSales IS NULL THEN 0
        else PrvYrSales
        end as prevYearSales,

        case
        when SalesGrwth IS NULL THEN 0
        else SalesGrwth * 100
        end as salesGrowth,

        case
        when YrBfrLst IS NULL THEN 0
        else YrBfrLst
        end as yearBeforeLast,

        case
        when BfrLstGrwth IS NULL THEN 0
        else BfrLstGrwth * 100
        end as yearBeforeLastGrowth

from    BigEMasterData.dbo.monthtmp as a

        left outer join BigESales.dbo.tbl_ReportCOMPANYperCust as b
        on b.Mon = a.monthNo
        or b.Mon is null

结果是上面的截图。

你能帮助我,或至少告诉我为什么我没有得到理想的结果?

非常感谢你。任何建议都将受到高度赞赏。

编辑:已解决:使用Yogesh的帮助谢谢你。



;WITH CTE AS (
    SELECT * FROM tbl_ReportCOMPANYperCust r 
    WHERE Cust = 'AFP035'
	and Yr = 2016
)

SELECT 
       r.CustNm as company, r.Cust as customer, r.Cust as custCode, 
       a.monthNo, a.monthName, r.Yr as Year, 
       COALESCE(NetSales, 0) as netSales, 
       COALESCE(PrvYrSales, 0) as prevYearSales, 
       COALESCE(SalesGrwth*100, 0) as salesGrowth, 
       COALESCE(YrBfrLst, 0) as yearBeforeLast, 
       COALESCE(BfrLstGrwth*100, 0) as yearBeforeLastGrowth  
FROM BigEMasterData.dbo.monthtmp a
LEFT OUTER JOIN CTE r on r.Mon = a.monthNo




结果如下。 : enter image description here

2 个答案:

答案 0 :(得分:2)

让我更正你的查询,为了得到所有月份,那么你的calendar表应该先表

SELECT 
       r.CustNm as company, r.Cust as customer, r.Cust as custCode, 
       a.monthNo, a.MontName, r.Yr as Year, 
       COALESCE(NetSales, 0) as netSales, 
       COALESCE(PrvYrSales, 0) as prevYearSales, 
       COALESCE(SalesGrwth*100, 0) as salesGrowth, 
       COALESCE(YrBfrLst, 0) as yearBeforeLast, 
       COALESCE(BfrLstGrwth*100, 0) as yearBeforeLastGrowth  
FROM monthtmp a
LEFT OUTER JOIN tbl_ReportCOMPANYperCust r on r.Mon = a.monthNo

使用ANSI SQL标准COALESCE()函数检查NULL

为了使所有月份名称都使用CTESubquery来保存过滤后的记录

;WITH CTE AS (
    SELECT * FROM tbl_ReportCOMPANYperCust r 
    WHERE Cust = 'AFP035'
    and Yr = 2016
)

SELECT 
       COLAESCE(r.CustNm, LAG(r.CustNm) OVER (ORDER BY a.monthNo)) as company, 
       COLAESCE(r.Cust, LAG(r.Cust) OVER (ORDER BY a.monthNo)) as customer, 
       COLAESCE(r.Cust, LAG(r.Cust) OVER (ORDER BY a.monthNo)) as custCode, 
       a.monthNo, a.monthName, r.Yr as Year, 
       COALESCE(NetSales, 0) as netSales, 
       COALESCE(PrvYrSales, 0) as prevYearSales, 
       COALESCE(SalesGrwth*100, 0) as salesGrowth, 
       COALESCE(YrBfrLst, 0) as yearBeforeLast, 
       COALESCE(BfrLstGrwth*100, 0) as yearBeforeLastGrowth  
FROM BigEMasterData.dbo.monthtmp a
LEFT OUTER JOIN CTE r on r.Mon = a.monthNo

答案 1 :(得分:1)

您似乎想要:

SELECT c.company, c.customer, c.custCode, 
       m.monthNo, m.monthName, c.Year, 
       COALESCE(r.NetSales, 0) as netSales,
       COALESCE(r.PrvYrSales, 0) as prevYearSales, 
       COALESCE(r.SalesGrwth*100, 0) as salesGrowth,
       COALESCE(r.YrBfrLst, 0) as yearBeforeLast, 
       COALESCE(r.BfrLstGrwth*100, 0) as yearBeforeLastGrowth  
FROM (SELECT DISTINCT r.CustNm as company, r.Cust as customer, r.Cust as custCode, r.Yr as Year
      FROM tbl_ReportCOMPANYperCust
      WHERE c.Cust = 'AFP035'
     ) c CROSS JOIN
     BigEMasterData.dbo.monthtmp m LEFT OUTER JOIN 
     tbl_ReportCOMPANYperCust r 
     ON r.Mon = m.monthNo AND r.Cust = c.customer
ORDER BY m.monthNo;

注意CROSS JOIN。这会带来初始列,因此您甚至可以使用与数据不匹配的月份。