Sql右外连接忽略所有空行

时间:2017-11-02 07:51:54

标签: sql sql-server sql-server-2008

旧SQL查询

SELECT 
    ISNULL(SUM(ColValue1), 0.00) AS Rejection 
FROM 
    Tabel1 a, Table2 b, Table3 c 
WHERE 
    b.col1 =* a.col2 
    AND c.col1 = a.col3 
    AND b.colx = 'xxxxxxx' 
    AND YEAR(TDate) = 2017 
    AND MONTH(TDate) = 11 
GROUP BY 
    c.columnz 
ORDER BY 
    c.columnZ

根据c.columnz返回15行:

Rejection   
-----------
0.02897429    
0.02215681      
0.00000000    
0.00000000    
0.00000000    
0.58119017   
0.24542928   
1.17601530    
1.41633147  
0.00000000   
0.00000000  
0.51131100    
0.00000000    
1.10613613   
0.09033161   

将查询转换为SQL Server 2008之后:

SELECT 
    ISNULL(SUM(ColValue1), 0.00) AS Rejection 
FROM
    Table2 b  
RIGHT OUTER JOIN 
    Tabel1 a ON b.col1 = a.col2
    ,Table3 c 
WHERE 
    c.col1 = a.col3 
    AND b.colx = 'xxxxxxx' 
    AND YEAR(TDate) = 2017 
    AND MONTH(TDate) = 11 
GROUP BY 
    c.columnz 
ORDER BY 
    c.columnZ

查询只返回9行(忽略所有空行)

Rejection    
----------
0.02897429   
0.02215681    
0.58119017   
0.24542928   
1.17601530   
1.41633147   
0.51131100   
1.10613613   
0.09033161   

请帮我修复新查询并让它返回所有15行。

所有三个表格和列

SELECT
    [REJ_CODE], [REJ_GROUPING], [TYPE]
FROM 
    [QAApr2006].[dbo].[Reject_Group];

SELECT
    [REJ_RKEY], [REJECT_CODE], 
    [REJECT_DESCRIPTION], [REJECT_ABBRV]
FROM
    [QAApr2006].[dbo].[Reject_Code];

SELECT
    [PR_GRP_CODE], [PROD_CODE],
    [CUSTOMER_PART_DESC], [TDATE],
    [REJ_CODE], [REJ_PARTS], [REJ_M2],
    [P_TYPE], [WO_Number],
    [REJ_CODE_ABBRV], [REJECT_DESCRIPTION]
FROM 
    [QAApr2006].[dbo].[QA_Rej_Det1];

1 个答案:

答案 0 :(得分:0)

尝试2

“c下面的评论中.REJ_GROUPING有15行而且b。[Tdate]”所以我按如下方式颠覆了查询:​​

SELECT
      ISNULL(SUM(REJ_M2), 0.00) AS rejection
FROM [QAApr2006].[dbo].Reject_Group c
LEFT JOIN [QAApr2006].[dbo].Reject_Code a ON c.REJ_CODE = a.REJECT_CODE
LEFT JOIN [QAApr2006].[dbo].QA_Rej_Det1 b ON a.REJ_RKEY = b.REJ_CODE
            AND b.CUSTOMER_PART_DESC = '0115761002'
            AND b.[Tdate] >= '20171101'
            AND b.[Tdate] < '20171201'
GROUP BY
      c.REJ_GROUPING
ORDER BY
      c.REJ_GROUPING

有效(尽管确认评论已在其他地方添加)。

原: 别名b在where clause中使用,因此它很可能是我们在from clause中首先使用的表,因此外连接现在是左连接。

SELECT
      ISNULL(SUM(REJ_M2), 0.00) AS rejection
FROM [QAApr2006].[dbo].QA_Rej_Det1 b
LEFT JOIN [QAApr2006].[dbo].Reject_Code a ON b.REJ_CODE = a.REJ_RKEY
LEFT JOIN [QAApr2006].[dbo].Reject_Group c ON a.REJECT_CODE = c.REJ_CODE
WHERE b.CUSTOMER_PART_DESC = '0115761002'
AND TDate >= '20171101'
AND TDate < '20171201'
GROUP BY
      REJ_GROUPING
ORDER BY
      Rej_Grouping

没有充分的理由使用YEAR()和MONTH()来获得准确的日期范围过滤器,只需指定您想要的月份的第一个日期和下个月的第一个日期。

此查询严重受到影响的另一件事是REJ_M2REJ_GROUPINGTdate没有表别名,所以我真的不知道左连接是否有效。使用表别名引用 EVER 列(如果未提供别名,则引用表名称)。

----

作为一个个人笔记,我真的讨厌在查询中指示序列的别名(a,b,c ...),因为如果我们需要突然重新排序那些别名真的很痛苦。我更喜欢“第一个字母”或“每个字母的第一个字母”作为别名方法,例如

SELECT
      ISNULL(SUM(rc.REJ_M2), 0.00) AS rejection
FROM [QAApr2006].[dbo].QA_Rej_Det1 q
LEFT JOIN [QAApr2006].[dbo].Reject_Code rc ON q.REJ_CODE = rc.REJ_RKEY
LEFT JOIN [QAApr2006].[dbo].Reject_Group rg ON rc.REJECT_CODE = rg.REJ_CODE
WHERE q.CUSTOMER_PART_DESC = '0115761002'
AND q.TDate >= '20171101'
AND q.TDate < '20171201'
GROUP BY
      q.REJ_GROUPING
ORDER BY
      q.Rej_Grouping

此变体可能无效,因为列别名只是猜测,&amp;我不是在解决这个问题。