SQL左连接不返回左

时间:2017-10-31 13:56:10

标签: sql left-join

我尝试过以下SQL查询,但我似乎无法从左表中获取所有值。如果右边有一个匹配的话,似乎让他们感到震惊

SELECT B.ITMREF_0, B.CPNITMREF_0, B.BOMSEQ_0,
       B1.CPNITMREF_0, B1.BOMSEQ_0, B.YREF_0, B1.YREF_0 
FROM [BOMD] as B
    LEFT JOIN [BOMD] as B1
        on B.CPNITMREF_0=B1.ITMREF_0 AND B.BOMALT_0=B1.BOMALT_0
WHERE B.ITMREF_0='50' 
    and B.BOMALT_0='1'

项目必须具体,BOMALT必须为1。 我已经尝试将WHERE语句添加到ON中,但这不能正确过滤。 有任何想法吗? 谢谢

编辑:谢谢你的回复: 示例数据:抱歉,我必须更改数据以显示

BOMD表

ITMREF_0  CPNITMREF_0  BOMSEQ_0 BOMALT_0 YREF_0
50        120-001      1        1        F1
50        112-001      2        1        F2
50        110-001      3        1        F3
112-001   113-001      1        1        P2
112-001   113-001      2        1        P3
50        120-001      1        2        D1
50        112-001      2        2        D2
50        110-001      3        2        D3
112-001   113-001      1        2        Q2
112-001   113-001      2        2        Q3

期望的结果

ITMREF_0  CPNITMREF_0  BOMSEQ_0  CPNITREF_0     BOMSEQ_0 YREF_0 YREF_0
50        120-001      1         NULL           NULL     F1     NULL
50        112-001      2         NULL           NULL     F2     NULL
50        112-001      2         113-001        1        NULL   P2
50        112-001      2         113-001        2        NULL   P3
50        110-001      3         NULL           NULL     F3     NULL

3 个答案:

答案 0 :(得分:0)

评论太长了。第一个问题:你明白“左表”是指“第一张表”吗?我知道我可以混淆“左”和“右”,所以我只想确定。

您的查询应该返回与BOMD完全相同的行:

SELECT B.*
FROM BOMD B
WHERE B.ITMREF_0 = '50' AND B.BOMALT_0 = '1';

由于多个匹配项,您的查询中可能会复制某些行。但是这些行都不应该被过滤掉。

另外,不要在数字常量周围使用单引号。如果列是数字 - 则删除单引号。

答案 1 :(得分:0)

你确定这部分是正确的吗?:

B.CPNITMREF_0=B1.ITMREF_0

因为那时你继续在where子句中指定:

B.ITMREF_0='50'

你想要加入左表列A等于右表列B,然后指定左表的列B应该是特定的东西,这似乎很奇怪。它显然是有效的SQL,但是没有看到或理解实际数据,很难说。

答案 2 :(得分:0)

我不明白为什么你会使用你的查询得到那些想要的结果。

具体而言(结果中的第2行)

ITMREF_0  CPNITMREF_0  BOMSEQ_0  CPNITREF_0     BOMSEQ_0 YREF_0 YREF_0
50        112-001      2         NULL           NULL     F2     NULL
匹配到B1时,

和Yref_0中的空值。 (结果中的第3/4行) 它们不应该也是'F2'吗?

基本问题: 使用外部联接时,您无法匹配,并且在没有某种联合的情况下,它在同一集合中的行为就像没有匹配记录一样。 B1中的B 2中的1 rec给你2条记录...不是3. 1 * 2 = 2得到3我们必须在缺失的记录中结合...

我怀疑这就是你现在所得到的: enter image description here

为了获得你想要的东西,我认为你需要在你想要的记录中联合,并使用一些特殊的逻辑逻辑以你想要的方式显示yref_0。第二条记录不在您的结果中的原因是因为它在左侧连接中找到,因此CPNitemRef_0记录的空值将不存在。

  • 使左连接成为内部(我们只想要匹配)(2条记录)
  • 联合您基地的记录,以便获得所有这些记录(包括匹配的112-001(3条记录)
  • 使用case语句从你想要的方式控制YREF上的空值。

Working DEMO:

SELECT B.ITMREF_0, B.CPNITMREF_0, B.BOMSEQ_0 BOMSEQ,
       B1.CPNITMREF_0, B1.BOMSEQ_0, case when B1.ITMREF_0 is null then B.YREF_0 else null end as itemRef_0, B1.YREF_0 
FROM BOMD  B
INNER JOIN BOMD B1
  on B.CPNITMREF_0=B1.ITMREF_0 
 AND B.BOMALT_0=B1.BOMALT_0
WHERE B.ITMREF_0='50' 
  and B.BOMALT_0= 1
UNION 
SELECT B.ITMREF_0, B.CPNITMREF_0, B.BOMSEQ_0,
       NULL, NULL, B.YREF_0, NULL
FROM BOMD B
WHERE B.ITMREF_0='50' 
  and B.BOMALT_0= 1;

给我们:

enter image description here

如果订单有问题,可能需要添加ORDER BY BOMSEQ, BOMSEQ_0;