使用SQL比较两个表,同时忽略空列

时间:2018-02-17 10:19:32

标签: sql postgresql

我想比较SQL(postgres)中两个表的内容。这些表具有匹配的模式。作为输出,我想要那些不同的行。 我已经检查了各种方法(也有一些在Stackoverflow上发布),但对我来说,当两列中的字段都为NULL时,我看起来有问题。这是我到目前为止所提出的:

~ $ echo $PATH
/home/asarluhi/.rvm/bin:/home/asarluhi/.rvm/bin:/home/asarluhi/.rvm/gems/ruby-2.3.1/bin:/home/asarluhi/.rvm/gems/ruby-2.3.1@global/bin:/home/asarluhi/.rvm/rubies/ruby-2.3.1/bin:/home/asarluhi/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/asarluhi/.rvm/bin:/home/asarluhi/.rvm/bin:/home/asarluhi/.rvm/bin:/usr/local/heroku/bin:/home/asarluhi/bin

所以在所有列上进行完全外连接,然后返回其中一个ID为空的那些。

但是通过这个查询,我得到了一些示例数据:

 
 dipi_id     dipi_foo     dipi_bar    rvdii_id     rvdii_foo   rvdii_bar   
 3           2016-01-01   NULL        NULL         NULL        NULL
 NULL        NULL         NULL        3            2016-01-01  NULL

正如您所见," dipi_bar"," rvdii_bar" columns包含一个空值,在连接中不匹配(我理解这一点)。因此,在上面的情况下,我不想要任何输出,我希望当两个列/字段都为NULL时,它们会匹配"在连接中(或在连接中忽略,无论什么工作)。这样做的诀窍是什么?

编辑:当然列并不总是为空,因此从连接中删除不是一个选项:)

3 个答案:

答案 0 :(得分:0)

我认为你想看到两个表中具有相同id的行,在其他两个字段上有差异。如果是这样的话,我认为以下内容可以胜任:

SELECT dipi.id AS dipi_id,dipi.foo AS dipi_foo,dipi.bar AS dipi_bar, rvdii.id AS rvdii_id,rvdii.foo AS rvdii_foo,rvdii.bar AS rvdii_bar
FROM schema1.mytable dipi
INNER JOIN schema2.mytable rvdii on dipi.id = rvdii.id 
WHERE (dipi.foo <> rvdii.foo OR (dipi.foo IS NULL AND rvdii.foo IS NOT NULL) OR (dipi.foo IS NOT NULL AND rvdii.foo IS NULL))
OR (dipi.bar <> rvdii.bar OR (dipi.bar IS NULL AND rvdii.bar IS NOT NULL) OR (dipi.bar IS NOT NULL AND rvdii.bar IS NULL))

答案 1 :(得分:0)

使用NULL - 安全比较运算符is not distinct from。请注意,WHERE子句也需要更改。 Postgres没有xor运算符,但你可以这样做:

SELECT dipi.id AS dipi_id,dipi.foo AS dipi_foo,dipi.bar AS dipi_bar,
       rvdii.id AS rvdii_id,rvdii.foo AS rvdii_foo,rvdii.bar AS rvdii_bar
FROM schema1.mytable dipi FULL OUTER JOIN
     schema2.mytable rvdii 
     ON dipi.id IS NOT DISTINCT FROM rvdii.id AND
        dipi.foo IS NOT DISTINCT rvdii.foo AND
        dipi.bar IS NOT DISTINCT FROM rvdii.bar
WHERE dipi.id IS DISTINCT FROM rvdii.id OR
      dipi.foo IS DISTINCT FROM rvdii.foo OR
      dipi.bar IS DISTINCT FROM rvdii.bar;

由于代码允许NULL中的ON匹配,因此您无法检查NULL过滤条件的WHERE

答案 2 :(得分:0)

回答我自己的问题:我最终使用了来自https://stackoverflow.com/a/18736060/1368432的方法,该方法使用UNIONEXCEPTINTERSECT来获取正确的结果集。对于我的情况,这是最简单的方法。