左联接实现减号不起作用

时间:2019-01-03 19:00:42

标签: sql google-bigquery

我有table1和table2如下:

表1: enter image description here

表2: enter image description here

当我在表之间执行以下查询时:

SELECT
  a.*
FROM
  (
    SELECT
      empid
     ,ename
     ,sal
     ,deptno
    FROM
      table1
    GROUP BY
      1,2,3,4
  ) AS a
LEFT JOIN
  (
    SELECT
      empid
     ,ename
     ,sal
     ,deptno
    FROM
      table2
  ) AS b
    ON
    a.empid = b.empid
      AND a.ename = b.ename
      AND a.sal = b.sal
      AND a.deptno = b.deptno
WHERE
  b.empid IS NULL
  AND b.ename IS NULL
  AND b.sal IS NULL
  AND b.deptno IS NULL;

我得到如下输出: enter image description here

Bigquery中没有Minus。这就是执行Left Join的原因。

我需要的输出是Table1减去table2。

请帮助我。

谢谢

2 个答案:

答案 0 :(得分:3)

以下是用于BigQuery标准SQL

#standardSQL
SELECT * FROM `project.dataset.table1`
EXCEPT DISTINCT
SELECT * FROM `project.dataset.table2`

答案 1 :(得分:0)

不太确定您的查询如何产生该输出,因为派生表A中只有4列,但是您声称输出产生8列

我认为可以简化:

SELECT a.* FROM table1 a LEFT JOIN table 2 b on a.empid = b.empid WHERE b.empid is null

当然,主键的要点是唯一地标识一行,因此我们只需要联接它,我们通常就不会将其他数据纳入我们是否应该返回该行的问题中。是“ 列表中的哪些雇员不在那个列表中?”

如果b.empid是一个PK,则它可以为null的唯一方法是联接无法解决,因此它是我们唯一需要测试其为null的列

您问

  

“为什么我所有的b列都为空?”

这是因为您已加入所有列,而不仅仅是加入主键:

  ON
  a.empid = b.empid
  AND a.ename = b.ename
  AND a.sal = b.sal
  AND a.deptno = b.deptno

数据库世界中的一条硬规则是:“没有什么等于空,甚至没有另一个空”

1 = NULL --false
'a' = NULL --false
'NULL' = NULL --false
NULL = NULL --false

如果一侧为空,则永远不能使用=(或其他任何运算符,如<,>,LIKE)从比较中得出TRUE。使用空值时唯一会产生TRUE的是IS NULL运算符(而且也不是NULL)

1 IS NULL --false
NULL IS NULL --true

返回查询时,请记住“如果=一侧的内容为空,则结果为FALSE”

这是您的行:

enter image description here

以下是B表行为空的原因:

EMPID   Reason
null    a.empid is null, a.empid = b.empid is FALSE because nothing is 
        ever equal to a null, no row from B is matching
101     a.sal is null, a.sal = b.sal is FALSE because nothing is ever 
        equal to a null, no row from B is matching, B is all null
104     a.deptno is null, a.deptno = b.deptno is FALSE because nothing is
        ever equal to a null, no row from B is matching, B is all null
105     a.sal is null, see reason for 101
102     there is no row for empid 102 in table b, b is all null
103     there is no row for empid 103 in table b, b is all null

那么您就可以了-由于没有匹配的行,或者因为您要求数据库在a.somecolumn = b.somecolumn上联接,并且至少一侧是=,并使用{ {1}}始终为false,false->没有匹配的行->所有B列均为空

您应该怎么做才能“修复”它?

要么像我上面说的那样仅连接主键(记住您的主键之一为null,这样它就永远不会出现),或者将null转换为可以与=进行比较的东西,如下所示:

NULL = anything

COALESCE从左到右工作,返回不为空的第一个参数。因此,如果a.sal为空,则COALESCE(a.sal,-1)将返回-1