如何从SQL中获取唯一的行集,其中唯一性由2列定义?

时间:2010-02-08 23:32:32

标签: sql tsql

如果我有一张表格如下:

ID |名称|类别|家长|网址|上次更改

如果两行具有相同的Name和parent,则它们不是唯一的。在这种情况下,如何获得唯一的行集(但返回的列数多于使它们唯一的列)?

所以,更多细节: 这是一个公司关键字表,其中关键字按类别进行组织。每个关键字只能有一个类别。每个关键字都可以有子关键字,因此如果parent = 0或NULL,则它是一个root关键字。如果关键字在类别中具有相同的名称和父级,则它们不是唯一的(无论其他列如何)。如果两个关键字具有相同的名称和类别,并且parent = 0或NULL,则它们不是唯一的。如果有重复,那么我只想要第一个。原因是我将这些放入一个系统中,该系统不允许关键字有两个具有相同名称的子项。

我还想看看哪些行重复,看看是什么原因造成了我的麻烦!

到目前为止,感谢一百万人的出色回应。我显然不是一个SQL人...... :(

4 个答案:

答案 0 :(得分:7)

这取决于您对非唯一行的操作。如果您不想在结果集中使用它们,可以使用group by并具有:

select Name, Parent, Max(Category) 
from Table
group by Name, Parent
having count(*) = 1

您需要Max(类别),因为您没有按该列进行分组,即使每个Name和Parent只有一行。

但是,如果要在结果中包含非唯一行,则类似于:

select distinct Name, Parent, Category from Table

除了具有相同Name和Parent但不同Category的两行仅返回单行。在这种情况下,您需要确定要为Category显示的内容,因为多行会被压缩为一行。您仍然可以使用Max(类别)或Min(类别)和分组依据,但不要使用。

select Name, Parent, Max(Category) 
from Table
group by Name, Parent

答案 1 :(得分:4)

此查询查找没有其他行具有相同名称和父级的所有行。如果两行的父级设置为NULL,则不认为这些行具有相同的父级。

SELECT T1.*
FROM Table1 T1
LEFT JOIN Table1 T2
ON T1.ID != T2.ID AND T1.Name = T2.Name AND T1.Parent = T2.Parent
WHERE T2.ID IS NULL

答案 2 :(得分:2)

您可以使用row_number函数按名称和父分区进行分区,例如:

select *
from (
    select
        row_number() over (partition by Name, Parent 
                           order by Name, Parent) as rn
    ,   *
    from YourTable
) sub
where rn = 1 -- Only first row for a name/parent combination

如果您只想选择唯一的行,从某种意义上说,不存在具有相同名称和父级的其他行,请尝试:

select *
from YourTable a
where (
    select count(*)
    from YourTable b
    where a.Name = b.Name
    and a.Parent = b.Parent
) = 1

答案 3 :(得分:1)

select x,y,z
from tablename t1
where not exists (select 1 from tablename t2 where t2.name = t1.name and t1.parent = t2.parent and t2.id <> t1.id)
根据表格大小,

可能会运行缓慢