T-SQL 完整的外部联接语句不包括联接 table 中的唯一值

T-SQL Full Outer Join Statement not including unique values from joined table

我有一个 T-SQL 语句应该执行 Full OUTER JOIN

我会调用原始的select语句table1,我会调用加入的tabletable2.

我的查询没有返回在 table2 中唯一的值。更具体地说,它不会返回 table2 具有不在 table1 中的 segValue1 或 segValue2 的行。 (即它错误地表现得好像连接是 LEFT JOIN 而不是 FULL OUTER JOIN)。

我不明白为什么要这样做。为什么这会表现得好像是左连接?

基本上发生的事情是,如果帐户没有 activity/does 不存在于实际值 table 中,那么它就不会被提取。

这里是 Table A、Table B、当前结果 Table 和期望结果 table:

的示例
Table Actual (SQL Server table with Actuals)
company  segValue1  segValue2 ActualsAmount FiscalYear FiscalPeriod
NVV        5000        000                 2017         12
NVV        6000        111        0        2017         12
NVV        8000        333                 2017         12
NVV        4000        555        0        2017         12


Table Budget (SQL Server table with Budgets)
company  segValue1  segValue2  BudgetAmt BalanceType FiscalYear FiscalPeriod
NVV        5000        000                D          2017        12
NVV        2000        111                D          2017        12
NVV        8000        444                D          2017        12
NVV        4000        555                D          2017        12


Table that the current, erroneous Code is producing. 
Notice it is skipping records 2 and 3 from Table B because it is not in Table A:

company  segValue1  segValue2     ActualsAmount       BudgetAmt
NVV        5000        000                                               
NVV        6000        111              0             NULL                
NVV        8000        333                            NULL  
NVV        8000        333                            NULL              
NVV        4000        555              0                


Desired Result Table:
company  segValue1  segValue2     ActualsAmount       BudgetAmt
NVV        5000        000                                               
NVV        6000        111              0             NULL   
NVV        2000        111              NULL                     --<-correct            
NVV        8000        444              NULL                     --<-correct    
NVV        8000        333                            NULL                
NVV        4000        555              0               

代码如下:

SELECT 
    A.Company, 
    A.segvalue1, A.segvalue2,      
    APYY.BalanceAmtBYTD, APYY.BalanceAmtBM, 
    SUM(CASE 
           WHEN FiscalPeriod BETWEEN '1' AND '12' AND FiscalYear = '2017' 
              THEN ActualsAmount 
              ELSE NULL 
        END) AS BalanceAmtCYTD, 
    SUM(CASE 
           WHEN FiscalPeriod = '12' AND FiscalYear = '2017' 
              THEN ActualsAmount
              ELSE NULL 
        END) AS BalanceAmtCYM
FROM 
    Actual  A

FULL OUTER JOIN

(SELECT 
         B.Company, B.segvalue1, B.segvalue2, 
         SUM(CASE WHEN FiscalPeriod BETWEEN '1' AND '12' AND FiscalYear = '2017' THEN BudgetAmt ELSE NULL END) as BalanceAmtBYTD, 
        SUM(CASE WHEN FiscalPeriod = '12' AND FiscalYear = '2017' THEN BudgetAmt ELSE NULL END) as BalanceAmtBM 
    FROM 
        Budget B 
    WHERE 
        FiscalYear = '2017' 
        AND BalanceType LIKE '%D%' 

    GROUP BY 
        B.Company, 
        B.segvalue1, B.segvalue2 ) APYY ON (A.Company = APYY.Company 
                                             AND A.segvalue1 = APYY.segvalue1 
                                             AND A.segvalue2 = APYY.segvalue2) 
WHERE 
    A.Company = 'NVV' 
GROUP BY 
    A.Company,  A.segvalue1,  A.segvalue2,
    APYY.BalanceAmtBYTD, APYY.BalanceAmtBM

我怀疑这会破坏它

WHERE GLJ.Company = 'NVV' 

这不仅是答案,也是解决问题的方法

declare @TableA table (Company varchar(5), segValue1 int, segValue2 int, ActualAmount int, FiscalYear int, FiscalPeriod int);
declare @TableB table (Company varchar(5), segValue1 int, segValue2 int, BudgetAmt int,    FiscalYear int, FiscalPeriod int);

insert into @TableA values 
             ('NVV', 5000, 000, 20, 2017, 12)
           , ('NVV', 6000, 111, 100, 2017, 12)
           , ('NVV', 8000, 333, 40, 2017, 12)
           , ('NVV', 4000, 555, 200, 2017, 12); 

insert into @TableB values 
             ('NVV', 5000, 000, 10, 2017, 12)
           , ('NVV', 2000, 111, 50, 2017, 12)
           , ('NVV', 8000, 444, 90, 2017, 12)
           , ('NVV', 4000, 555, 60, 2017, 12); 


select * from @TableA order by Company, segvalue1, segvalue2;

SELECT  B.Company, B.segvalue1, B.segvalue2, 
        SUM(CASE WHEN FiscalPeriod BETWEEN '1' AND '12' AND FiscalYear = '2017' THEN BudgetAmt ELSE NULL END) as BalanceAmtBYTD, 
        SUM(CASE WHEN FiscalPeriod = '12' AND FiscalYear = '2017' THEN BudgetAmt ELSE NULL END) as BalanceAmtBM 
FROM  @TableB B 
WHERE FiscalYear = '2017' 
GROUP BY B.Company, B.segvalue1, B.segvalue2 
ORDER BY B.Company, B.segvalue1, B.segvalue2; 

select isnull(A.Company, bb.Company) as Company, isnull(A.segvalue1, bb.segValue1) as segvalue1, isnull(A.segvalue2, bb.segValue2) as segvalue2, 
       bb.BalanceAmtBYTD, bb.BalanceAmtBM 
from @TableA a
full outer join ( SELECT  B.Company, B.segvalue1, B.segvalue2, 
                          SUM(CASE WHEN FiscalPeriod BETWEEN '1' AND '12' AND FiscalYear = '2017' THEN BudgetAmt ELSE NULL END) as BalanceAmtBYTD, 
                          SUM(CASE WHEN FiscalPeriod = '12' AND FiscalYear = '2017' THEN BudgetAmt ELSE NULL END) as BalanceAmtBM 
                    FROM  @TableB B 
                   WHERE  FiscalYear = '2017' 
                   GROUP BY  B.Company, B.segvalue1, B.segvalue2
                 ) bb
  on a.Company   = bb.Company
 and a.segValue1 = bb.segValue1
 and a.segValue2 = bb.segValue2
group by A.Company,   A.segvalue1,   A.segvalue2,  
         bb.Company,  bb.segvalue1,  bb.segvalue2,
         bb.BalanceAmtBYTD, bb.BalanceAmtBM 
order by isnull(A.Company, bb.Company), isnull(A.segvalue1, bb.segValue1), isnull(A.segvalue2, bb.segValue2);

我找到了一篇帮助我解决问题的文章。基本上我决定使用 Union All 并通过制作 "dummy" 列并将它们设置为零,然后在最后分组来解决 "same column name" 和 "equal number of columns" 联合特定要求问题。这个周末对我来说是一次巨大的学习经历。这个周末我了解了更多关于 tsql 的知识,然后我就把所有的时间都花在研究它上了。这是我发现这个 technique/structure "Better alternatives to outer joins" 的文章:http://weblogs.sqlteam.com/jeffs/archive/2007/04/19/Full-Outer-Joins.aspx

这是我最后的 T-SQL:

select 
Company,
segValue1,
segValue2,
segValue3,
segvalue4,


SUM(BalanceAmtCYTD) as BalanceAmtCYTD,
    SUM(BalanceAmtCYM) as BalanceAmtCYM,
    SUM(BalanceAmtAPYTD) as BalanceAmtAPYTD, 
    SUM(BalanceAmtBSPYBal) as BalanceAmtBSPYBal, 
    SUM(BalanceAmtBSCYBal) as BalanceAmtBSCYBal,
    SUM(BalanceAmtBSCYActivity) as BalanceAmtBSCYActivity,
    SUM(BalanceAmtBSCMActivity) as BalanceAmtBSCMActivity, 
    SUM(BalanceAmtAPYM) as BalanceAmtAPYM,
    SUM(BalanceAmtBYTD) as BalanceAmtBYTD,
    SUM(BalanceAmtBM) as BalanceAmtBM

From
(


Select
Company,
segValue1,
segValue2,
segValue3,
segvalue4,

SUM(CASE WHEN FiscalPeriod BETWEEN '1' AND '3' AND FiscalYear = '2018' THEN DebitAmount - CreditAmount END) as BalanceAmtCYTD, 
    SUM(CASE WHEN FiscalPeriod = '3' AND FiscalYear = '2018' THEN DebitAmount - CreditAmount  END) as BalanceAmtCYM, 
    SUM(CASE WHEN FiscalPeriod BETWEEN '1' AND '3' AND FiscalYear = '2017' THEN DebitAmount - CreditAmount  END) as BalanceAmtAPYTD, 
    SUM(CASE WHEN ((FiscalPeriod between '1' AND '3' AND FiscalYear = '2017') OR (FiscalYear < '2017')) THEN DebitAmount - CreditAmount  END) as BalanceAmtBSPYBal, 
    SUM(CASE WHEN ((FiscalPeriod between '1' AND '3' AND FiscalYear = '2018') OR (FiscalYear < '2018')) THEN DebitAmount - CreditAmount  END) as BalanceAmtBSCYBal, 
    SUM(CASE WHEN (FiscalPeriod between '1' AND '3') AND (FiscalYear = '2018') THEN DebitAmount - CreditAmount END) as BalanceAmtBSCYActivity, 
    SUM(CASE WHEN (FiscalPeriod = '3') AND (FiscalYear = '2018') THEN DebitAmount - CreditAmount END) as BalanceAmtBSCMActivity, 
    SUM(CASE WHEN (FiscalPeriod = '3') AND (FiscalYear = '2017') THEN DebitAmount - CreditAmount END) as BalanceAmtAPYM,
    0 as BalanceAmtBYTD,
    0 as BalanceAmtBM

    FROM GLJrnDtl
    where company = 'ovpca'
group by Company,
segValue1,
segValue2,
segValue3,
segvalue4

Union all

Select
Company,
segValue1,
segValue2,
segValue3,
segvalue4,

0 as BalanceAmtCYTD,
0 as BalanceAmtCYM,
0 as BalanceAmtAPYTD,
0 as BalanceAmtBSPYBal,
0 as BalanceAmtBSCYBal,
0 as BalanceAmtBSCYActivity, 
0 as BalanceAmtBSCMActivity,
0 as BalanceAmtAPYM,

SUM(CASE WHEN  FiscalPeriod BETWEEN '1' AND '3' AND FiscalYear = '2018' THEN BudgetAmt ELSE NULL END) as BalanceAmtBYTD, 
SUM(CASE WHEN FiscalPeriod = '3' AND FiscalYear = '2018' THEN BudgetAmt ELSE NULL END) as BalanceAmtBM


from GLBudgetDtl
where Company = 'ovpca' and balancetype = 'd'

group by Company,
segValue1,
segValue2,
segValue3,
segvalue4
) x

Group by
Company,
segValue1,
segValue2,
segValue3,
segvalue4