2016-09-29 64 views
1

当我运行以下查询时,我将行从结果中排除,即使我知道它们应该在那里。我把范围缩小到5加入:
LEFT OUTER JOIN BDNDETL W于
W.CODE = B.WP
如果我删除加入和由别名简称列“W”,我得到的所有的我期望的行。 W中有一些行在B中没有匹配W.CODE = B.WP,但我认为LEFT OUTER条件会捕获这些,但事实并非如此。它似乎只是把它当作一个INNER JOIN来对待。外部加入排除行

SELECT 
    p.p2 AS "Section", 
    d.d9 AS "Alt WBS", 
    p.p3 AS "Year", 
    B.ca1 AS "WBS", 
    concat(b.ca1,'/',b.ca2,'/',b.wp,b.descrip) AS "Work Package", 
    B.WP, 
    w.d9 AS "Cost Category", 
    B.C3 AS "Provider", 
    b.c1 AS "TType", 
    w.d4 AS "WP GLA Cat", 
    U.COSTSET, 
    CONVERT(varchar, T.PD_FINISH, 101) period, 
    SUM(A.ALLOWANCE1 + A.ALLOWANCE2 + A.ALLOWANCE3 + A.ALLOWANCE4 + A.ALLOWANCE5 + A.BASIC + A.BONUS + A.COMMODITY + A.DIRECT + A.ENHANCED + A.NIERS + A.OVERTIME + A.PENSION + A.PILON + A.REDUNDANCY) Value 
FROM 
    TPHASE A JOIN CAWP B ON 
     B.PROGRAM = A.PROGRAM AND B.CAWPID = A.CAWPID 
      JOIN MULTPROG X ON 
       A.PROGRAM = X.SUBPROGRAM 
      JOIN PROGRAM P ON 
       A.PROGRAM = P.PROGRAM 
      JOIN BDNDETL D ON 
       D.CODE = B.CA1 
      LEFT OUTER JOIN BDNDETL W ON 
       W.CODE = B.WP 
      JOIN COSTDETL U ON 
       A.CLASS = U.CLASS 
      JOIN RCUTOFF T ON 
       A.DF_DATE BETWEEN T.PD_START AND T.PD_FINISH 
WHERE 
    X.MASTER = @master AND 
    D.BREAKFILE = @wbsfile AND 
    U.INSTANCE = @costdetlid AND 
    T.INSTANCE = @cutoffid AND 
    W.BREAKFILE = @wpbdn 
GROUP BY 
    p.p2, 
    d.d9, 
    p.p3, 
    B.ca1, 
    concat(b.ca1,'/',b.ca2,'/',b.wp,b.descrip), 
    B.WP, 
    w.d9, 
    B.C3, 
    b.c1, 
    w.d4, 
    U.COSTSET, 
    T.PD_FINISH 
; 
+2

问题在于where条件W.BREAKFILE = @wpbdn;在左连接的条件中包括这个[LEFT OUTER JOIN BDNDETL W ON W.CODE = B.WP AND W.BREAKFILE = @wpbdn –

回答

3

这种情况的WHERE子句中:

W.BREAKFILE = @wpbdn 

当没有匹配失败。为什么?因为W.BREAKFILENULL。你应该把它移动到合适的ON条款:

 LEFT OUTER JOIN BDNDETL W ON 
      W.CODE = B.WP AND W.BREAKFILE = @wpbdn 

而且,一个忠告。当你混合innerleft连接,我强烈建议你把所有的内连接第一其次是left join S:

FROM TPHASE A JOIN 
    CAWP B 
    ON B.PROGRAM = A.PROGRAM AND B.CAWPID = A.CAWPID JOIN 
    MULTPROG X 
    ON A.PROGRAM = X.SUBPROGRAM JOIN 
    PROGRAM P 
    ON A.PROGRAM = P.PROGRAM JOIN 
    BDNDETL D 
    ON D.CODE = B.CA1 JOIN 
    COSTDETL U 
    ON A.CLASS = U.CLASS JOIN 
    RCUTOFF T 
    ON A.DF_DATE BETWEEN T.PD_START AND T.PD_FINISH LEFT JOIN 
    BDNDETL W 
    ON W.CODE = B.WP 

这使得逻辑更容易跟踪。这个想法是,内部连接进行过滤,然后左连接说“保留所有这些行,并添加这些额外的列,如果他们匹配”。

3

你在你的where子句中有W.BREAKFILE = @wpbdn,左连接的空值不能通过这个过滤器。