我想在Toad中做一个SQL提取表中所有带有某些条件的值。我捕获了所有值,但是现在我想向SQL添加新条件,但是我不知道如何。我只想捕获不重复的值。例如:
我现在有这个:
PRINCIPAL APELLIDO NOMBRE
a b c
b c d
c d e
a l m
在这种情况下,我只想捕获PRINCIPAL
不重复的值,在此示例中,我只想捕获第二行和第三行,因为第一行和第四行是重复的。
答案 0 :(得分:3)
一种方法是您可以使用此查询:
SELECT principal,
MAX(apellido) AS apellido,
MAX(nombre) AS nombre
FROM table_name
GROUP BY principal
HAVING COUNT(*) = 1
ORDER BY principal;
答案 1 :(得分:1)
具有一个返回多次存在的PRINCIPAL值的子查询:
select *
from tablename
where PRINCIPAL not in (select PRINCIPAL from tablename
group by PRINCIPAL
having count(*) > 1)
答案 2 :(得分:1)
您可以使用COUNT
聚合函数来删除所有重复的行。
CreateCard
select PRINCIPAL, APELLIDO, NOMBRE,
count(*) over (partition by PRINCIPAL) dup_cnt
from tab
P A N DUP_CNT
- - - ----------
a b c 2
a l m 2
b c d 1
c d e 1
对COUNT
子句中定义的每个唯一键的行进行计数。
最终查询仅选择唯一行,即带有PARTITION BY
的行
DUP_CNT = 1
注意:使用ROW_NUMBER
而不是with dedup as (
select PRINCIPAL, APELLIDO, NOMBRE,
count(*) over (partition by PRINCIPAL) dup_cnt
from tab)
select PRINCIPAL, APELLIDO, NOMBRE
from dedup
where dup_cnt = 1
可以进行重复数据删除,即,让结果中重复的行之一并删除重复的行。
注意,此方法需要对表(COUNT
进行 sort 排序,对于大型表来说可能很重。在这种情况下,使用WINDOW SORT
的方法可能会产生更好的性能,因为它经过转换并作为反哈希联接-NOT EXISTS
执行。
HASH JOIN RIGHT ANTI
如果重复数据删除列(select principal, apellido, nombre
from tab t
where not exists
(select null
from tab
where principal = t.principal and rowid <> t.rowid
)
)可为空,则必须格外小心。与第一个解决方案principal
相反,COUNT
将所有not exusts
留在结果中。如果不需要,则必须添加一个过滤器:
null
如果您在 and t.principal is not NULL
列上有索引,则最佳执行计划如下所示
pricipal
答案 3 :(得分:1)
您可以使用窗口功能。逻辑将是:
select principal, apellido, nombre
from (select t.*, count(*) over (partition by principal) as cnt
from t
) t
where cnt = 1;
这将返回其中principal
是NULL
的行;这样的行由NOT EXISTS
消除。
但是,如果您拥有主键和(principal, pk)
上的索引,最快的方法可能是:
select principal, apellido, nombre
from t
where not exists (select 1
from t t2
where t2.principal = t.principal and t2.pk <> t.pk
);