left join其中b.key由两列为空

时间:2016-05-11 14:06:59

标签: sql postgresql

我有两张桌子。

  table_1       | table_2
id col_1 | col_2 | col_1 | col_2
1  1     | B     | 1     | B
2  1     | C     | 3     | C
3  1     | D     | 5     | D
....

我写这个查询

SELECT *
    FROM table_1 t1
    LEFT JOIN table_2 t2 ON t1.col_1 = t2.col_1
    WHERE t1.col_1 = 1
        AND (
            t2.col_1 IS NULL
            AND t2.col_1 != 'B'
            )

我想得到这个结果。

table_1          |
id col_1 | col_2 |
2  1     | C     |
3  1     | D     |

我该怎么做?谢谢!

更新问题

表1 - PriceItems,表2 - BlockedPrices,col1 - Code,col2 - Brand。

我想获取所有PriceItems的当前代码,并且所有品牌都会从BlockesPrices中删除代码。

3 个答案:

答案 0 :(得分:0)

认为这是您正在寻找的:

Select      t1.*
From        table_1 t1
Left Join   table_2 t2  On  t1.col_1 = t2.col_1
                        And t2.col_1 != 'B'
Where       t1.col_1 = 1
And         t2.col_1 Is Not Null

据我了解您的问题,您希望在第二个表格中执行LEFT JOIN,但请将t2.col_1 = 'B'排除在最终结果之外。

在这种情况下,您需要将条件t2.col_1 = 'B'移至ON条款,以便拥有与LEFT JOIN条件不匹配的记录回到NULL

您可能看到奇怪结果的原因是AND t2.col_1 != 'B'子句中的WHERE条件。这会导致过滤器在 LEFT JOIN之后发生,这将进一步过滤这些结果(从而有效地将LEFT JOIN转换为INNER JOIN

编辑,问题已更改:

根据问题中的新信息,您将第二个表用作排除表,并希望从第二个表中显示的结果中删除结果。

为此,您根本不需要JOIN,您可以使用WHERE NOT EXISTS执行以下操作:

Select  *
From    PriceItems  P
Where Not Exists
(
    Select  *
    From    BlockedPrices   B
    Where   P.Code = B.Code
    And     P.Brand = B.Brand
)
And     P.Code = 1

答案 1 :(得分:0)

这会产生你想要的输出,看起来更简单:

select t1.id, t1.col1, t1.col2
from t1 join
     t2
     on t2.col2 = t1.col2
where t1.col1 <> 'B';

严格来说,join不是必需的,但我认为你的真正问题更复杂。

答案 2 :(得分:0)

您只需要来自table_1的结果,因此您甚至不需要加入。

select * 
from table_1 t1
where not exists (
  select 1 
  from table_2 t2
  where t1.col_1 = t2.col_1 
    and t2.col_2 = t2.col_2
)

您可以在内部select语句中提供任何其他where条件,以指定哪些类型的匹配应取消列出table_1记录的资格。

例如,您可以将and t2.price > 2000添加到内部where条件,以取消table_1中所有与table_2中的匹配记录且价格高于2000的记录的资格。