仅选择不包含重复值的行

时间:2017-10-10 18:22:39

标签: sql

上下文

我有一个表,其列的行为类似于“键”值。相同的键值可能出现在多行中,我希望SELECT只包含不包含在多行中的键的行。例如,如果输入表是:

key  |  col1  |  col2  |  other columns
_______________________________________
1       1337     1338
1       1339     1340
2       1341     1342
3       1343     1344
3       1345     1346
4       1347     1348
5       1349     1350
5       1351     1352
5       1353     1354

输出应为:

key  |  col1  |  col2  |  other columns
_______________________________________
2       1341     1342
4       1347     1348

问题

我可以在不填充第三张表的情况下有效地执行此操作吗?

我尝试过什么

SELECT key, col1, col2, other columns
FROM input_t
WHERE COUNT(col1) = 1
GROUP BY key

但是,这不是有效的查询。如果col1为NULL,该怎么办?我仍然想要行(key,col2,其他列)。

SELECT key, col1, col2, other columns
FROM input_t
GROUP BY key
HAVING COUNT(col1) = 1

也不是有效的查询。

我尝试过使用DISTINCT,但这并不会忽略多次出现的密钥。对于我来说,聚合其他列也没有逻辑意义。

3 个答案:

答案 0 :(得分:3)

如果密钥永远不是NOT IN

,只需使用NULL即可
SELECT key, col1, col2, other columns
FROM input_t
WHERE key NOT IN (
   SELECT key
   FROM input_t
   GROUP BY key
   HAVING COUNT(col1) > 1
)

答案 1 :(得分:1)

如果您愿意,可以使用聚合:

SELECT key, min(col1) as col1, min(col2) as col2, . . .
FROM input_t
GROUP BY key
HAVING COUNT(col1) = 1;

只有一行,min()是值。

为提高效率,最好的可能是:

select t.*
from input_t t
where not exists (select 1
                  from input_t t2
                  where t2.key = t.key and t2.col1 <> t.col1
                 );

这假设每个键col1是唯一的(就像您的数据一样)。

这可以利用input_t(key, col1)上的索引。

答案 2 :(得分:1)

如何

SELECT *
FROM input_t
WHERE key IN (
   SELECT key
   FROM input_t
   GROUP BY key
   HAVING COUNT(key) = 1)

SELECT i.*
FROM 
 input_t i inner join
(select 
  key 
from 
  input_t 
group by 
  key 
having 
  count(key) = 1) k on 
i.key = k.key