如果我有一张表格如下:
ID |名称|类别|家长|网址|上次更改
如果两行具有相同的Name和parent,则它们不是唯一的。在这种情况下,如何获得唯一的行集(但返回的列数多于使它们唯一的列)?
所以,更多细节: 这是一个公司关键字表,其中关键字按类别进行组织。每个关键字只能有一个类别。每个关键字都可以有子关键字,因此如果parent = 0或NULL,则它是一个root关键字。如果关键字在类别中具有相同的名称和父级,则它们不是唯一的(无论其他列如何)。如果两个关键字具有相同的名称和类别,并且parent = 0或NULL,则它们不是唯一的。如果有重复,那么我只想要第一个。原因是我将这些放入一个系统中,该系统不允许关键字有两个具有相同名称的子项。
我还想看看哪些行重复,看看是什么原因造成了我的麻烦!
到目前为止,感谢一百万人的出色回应。我显然不是一个SQL人...... :(
答案 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)
根据表格大小,可能会运行缓慢