Sql 具有相同表和联接逻辑但结果不同的两个查询

Sql 具有相同表和联接逻辑但结果不同的两个查询,sql,google-bigquery,bigquery-standard-sql,Sql,Google Bigquery,Bigquery Standard Sql,我正在尝试只获取1个表中的记录,即A中的记录,而不是B中的记录 案例1: 案例2: select count(distinct col1) from `table2_*` where _table_suffix between '20180101' and '20181231' and col1 not in ( select distinct col1 from `table1` where date(timestamp_seconds(ts))>='2018-01-01' ) 在2个

我正在尝试只获取1个表中的记录,即A中的记录,而不是B中的记录 案例1:

案例2:

select count(distinct col1)
from `table2_*`
where _table_suffix between '20180101' and '20181231'
and col1 not in (
select distinct col1 from `table1`
where date(timestamp_seconds(ts))>='2018-01-01'
)
在2个代码中,case2起作用,而case1给出0作为输出。我还尝试将案例1作为表反转的左连接,但结果是相同的0行。我不熟悉大查询和标准sql版本,不知道为什么会发生这种情况

在2个代码中,case2起作用,而case1给出0作为输出

这是因为当列表中有空值时,
notin
返回空值。如果不希望出现这种行为,请排除空值:

select count(distinct col1)
from `table2_*`
where _table_suffix between '20180101' and '20181231'
and col1 not in (
select distinct col1 from `table1`
where date(timestamp_seconds(ts))>='2018-01-01'
and col1 IS NOT NULL
)
在2个代码中,case2起作用,而case1给出0作为输出

这是因为当列表中有空值时,
notin
返回空值。如果不希望出现这种行为,请排除空值:

select count(distinct col1)
from `table2_*`
where _table_suffix between '20180101' and '20181231'
and col1 not in (
select distinct col1 from `table1`
where date(timestamp_seconds(ts))>='2018-01-01'
and col1 IS NOT NULL
)

如果使用
不在
中,则不得允许将NULL作为“在列表中”的值

就个人而言,我更喜欢使用
不存在

SELECT count(DISTINCT t.col1)
FROM `table2_ * ` AS t
WHERE t._table_suffix BETWEEN '20180101' AND '20181231'
 AND NOT EXISTS (
  SELECT NULL
  FROM `table1` AS e
  WHERE DATE (timestamp_seconds(e.ts)) >= '2018-01-01'
   AND e.col1 = t.col1
  );

注意,这里的子查询select子句不需要返回任何值,因此
selectnull
select1
select*
都是有效的。使用
exits
not exists
时,子查询的from和where子句很重要。

如果使用
not IN
不能允许NULL作为“IN list”的值

就个人而言,我更喜欢使用
不存在

SELECT count(DISTINCT t.col1)
FROM `table2_ * ` AS t
WHERE t._table_suffix BETWEEN '20180101' AND '20181231'
 AND NOT EXISTS (
  SELECT NULL
  FROM `table1` AS e
  WHERE DATE (timestamp_seconds(e.ts)) >= '2018-01-01'
   AND e.col1 = t.col1
  );
注意,这里的子查询select子句不需要返回任何值,因此
selectnull
select1
select*
都是有效的。当使用
exits
not exists
时,子查询的from&where子句起作用