SQL 检查是否有 NULL 的重复项不 return
SQL that check for Duplicates with NULL doesn't not return
我正在使用 2 个单独的查询来检查重复项,并且这两个查询在执行时应该给出相同的答案,但事实并非如此。下面是我的数据库 table 数据的示例:
id Name Age Group SeatNo
------------------------------------------
1 Alpha 11 A NULL
2 Bravo 12 A 1
3 Alpha 11 B NULL
这是我的第一个查询,其中显示有重复项
SELECT count(*)
FROM Test AS ta
JOIN Test AS tb ON ta.name=tb.name AND ta.age=tb.age
WHERE ta.GroupName='A'
AND tb.GroupName='B'
这是我的第二个显示零重复的查询
SELECT count(*)
FROM Test AS ta
JOIN Test AS tb ON ta.name=tb.name AND ta.age=tb.age AND ta.SeatNo=tb.SeatNo
WHERE ta.GroupName='A'
AND tb.GroupName='B
在查看查询和 table 中的数据后,似乎 seatNo 中的 NULL 影响了第二个查询并导致它 return 0 次重复。是否有任何解决方案可以搜索重复项,即使它是 NULL?
对于第二个查询,您可以在 JOIN 中添加一个过滤条件
SELECT count(*)
FROM Test AS ta
JOIN Test AS tb ON ta.name=tb.name AND
ta.age=tb.age AND
( ta.SeatNo=tb.SeatNo OR (ta.SeatNo IS NULL AND tb.SeatNo IS NULL)
WHERE ta.GroupName='A'
AND tb.GroupName='B
你已经学会了NULL <> NULL
。你能做些什么?
好吧,ANSI SQL 有一个用于此目的的比较器 IS DISTINCT FROM
。所以,你可以这样写:
SELECT count(*)
FROM Test AS ta JOIN
Test AS tb
ON ta.name = tb.name AND ta.age = tb.age AND
NOT ta.SeatNo IS DISTINCT FROM tb.SeatNo
WHERE ta.GroupName = 'A' AND
tb.GroupName = 'B';
但是,大多数数据库不支持。更一般的形式是:
SELECT count(*)
FROM Test AS ta JOIN
Test AS tb
ON ta.name = tb.name AND ta.age = tb.age AND
(ta.SeatNo = tb.SeatNo OR (ta.SeatNo IS NULL AND tb.SeatNo IS NULL) )
WHERE ta.GroupName = 'A' AND
tb.GroupName = 'B';
另一种方法使用 UNION ALL
和聚合。以下获取重复项:
select name, age, SeatNo
from ((select name, age, SeatNo, 'a' as which
from test
where GroupName = 'A'
) union all
(select name, age, SeatNo, 'B' as which
from test
where GroupName = 'B'
)
) ab
group by name, age, seatno
having count(distinct which) = 2;
然后您可以将其用作子查询来获取计数:
select count(*)
from (select name, age, SeatNo
from ((select name, age, SeatNo, 'a' as which
from test
where GroupName = 'A'
) union all
(select name, age, SeatNo, 'B' as which
from test
where GroupName = 'B'
)
) ab
group by name, age, seatno
having count(distinct which) = 2
) ab;
您的第二个查询应该检查 NULL。试试,
SELECT count(*)
FROM Test AS ta
JOIN Test AS tb ON ta.name=tb.name AND ta.age=tb.age AND ISNULL(ta.SeatNo,'')=ISNULL(tb.SeatNo,'')
WHERE ta.GroupName='A'
AND tb.GroupName='B
我正在使用 2 个单独的查询来检查重复项,并且这两个查询在执行时应该给出相同的答案,但事实并非如此。下面是我的数据库 table 数据的示例:
id Name Age Group SeatNo
------------------------------------------
1 Alpha 11 A NULL
2 Bravo 12 A 1
3 Alpha 11 B NULL
这是我的第一个查询,其中显示有重复项
SELECT count(*)
FROM Test AS ta
JOIN Test AS tb ON ta.name=tb.name AND ta.age=tb.age
WHERE ta.GroupName='A'
AND tb.GroupName='B'
这是我的第二个显示零重复的查询
SELECT count(*)
FROM Test AS ta
JOIN Test AS tb ON ta.name=tb.name AND ta.age=tb.age AND ta.SeatNo=tb.SeatNo
WHERE ta.GroupName='A'
AND tb.GroupName='B
在查看查询和 table 中的数据后,似乎 seatNo 中的 NULL 影响了第二个查询并导致它 return 0 次重复。是否有任何解决方案可以搜索重复项,即使它是 NULL?
对于第二个查询,您可以在 JOIN 中添加一个过滤条件
SELECT count(*)
FROM Test AS ta
JOIN Test AS tb ON ta.name=tb.name AND
ta.age=tb.age AND
( ta.SeatNo=tb.SeatNo OR (ta.SeatNo IS NULL AND tb.SeatNo IS NULL)
WHERE ta.GroupName='A'
AND tb.GroupName='B
你已经学会了NULL <> NULL
。你能做些什么?
好吧,ANSI SQL 有一个用于此目的的比较器 IS DISTINCT FROM
。所以,你可以这样写:
SELECT count(*)
FROM Test AS ta JOIN
Test AS tb
ON ta.name = tb.name AND ta.age = tb.age AND
NOT ta.SeatNo IS DISTINCT FROM tb.SeatNo
WHERE ta.GroupName = 'A' AND
tb.GroupName = 'B';
但是,大多数数据库不支持。更一般的形式是:
SELECT count(*)
FROM Test AS ta JOIN
Test AS tb
ON ta.name = tb.name AND ta.age = tb.age AND
(ta.SeatNo = tb.SeatNo OR (ta.SeatNo IS NULL AND tb.SeatNo IS NULL) )
WHERE ta.GroupName = 'A' AND
tb.GroupName = 'B';
另一种方法使用 UNION ALL
和聚合。以下获取重复项:
select name, age, SeatNo
from ((select name, age, SeatNo, 'a' as which
from test
where GroupName = 'A'
) union all
(select name, age, SeatNo, 'B' as which
from test
where GroupName = 'B'
)
) ab
group by name, age, seatno
having count(distinct which) = 2;
然后您可以将其用作子查询来获取计数:
select count(*)
from (select name, age, SeatNo
from ((select name, age, SeatNo, 'a' as which
from test
where GroupName = 'A'
) union all
(select name, age, SeatNo, 'B' as which
from test
where GroupName = 'B'
)
) ab
group by name, age, seatno
having count(distinct which) = 2
) ab;
您的第二个查询应该检查 NULL。试试,
SELECT count(*)
FROM Test AS ta
JOIN Test AS tb ON ta.name=tb.name AND ta.age=tb.age AND ISNULL(ta.SeatNo,'')=ISNULL(tb.SeatNo,'')
WHERE ta.GroupName='A'
AND tb.GroupName='B