Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get unique set of rows from SQL where uniqueness is defined by 2 columns?

Tags:

sql

tsql

If I have a table as follows:

ID | Name | Category | Parent | URL | LastModified

If two rows have the same Name and parent, then they are not unique. How do I get the unique set of rows in this case (but return more than the columns that make them unique)?

So, for more details: This is a corporate keywords table, where keywords are organized by category. Each keyword can only have one category. Each keyword can have child keywords, so if parent=0 or NULL, it is a root keyword. If keywords have the same name and parent in a category, then they are not unique (regardless of the other columns). If two keywords have the same name and category, and parent=0 or NULL then they are not unique. If there are duplicates, then I only want the 1st one. The reason is I am putting these into a system that will not allow a keyword to have two children with the same name.

I would also like to see what rows ARE duplicates to see what is causing me the trouble!

Thanks a million so far for excellent responses. I am obviously not a SQL guy... :(

like image 785
Donaldinio Avatar asked Feb 08 '10 23:02

Donaldinio


People also ask

How do I find distinct records based on two columns?

To get the identical rows (based on two columns agent_code and ord_amount) once from the orders table, the following SQL statement can be used : SQL Code: SELECT DISTINCT agent_code,ord_amount FROM orders WHERE agent_code='A002';

How do I count unique values in two columns in SQL?

but when we want to count distinct column combinations, we must either clumsily concatenate values (and be very careful to choose the right separator): select count(distinct col1 || '-' || col2) from mytable; or use a subquery: select count(*) from (select distinct col1, col2 from mytable);

How do I get unique rows in SQL query?

The SQL SELECT DISTINCT Statement The SELECT DISTINCT statement is used to return only distinct (different) values. Inside a table, a column often contains many duplicate values; and sometimes you only want to list the different (distinct) values.

Can I use distinct with multiple columns?

Answer. Yes, the DISTINCT clause can be applied to any valid SELECT query. It is important to note that DISTINCT will filter out all rows that are not unique in terms of all selected columns.


4 Answers

It depends on what you want to do with non-unique rows. If you want to not have them in the result set you could use group by and having:

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

You need the Max(Category) because you aren't grouping by that column, even though there will only be one row per Name and Parent.

If, though, you want to include non-unique rows in the result, similar to:

select distinct Name, Parent, Category from Table

except that two rows with the same Name and Parent but different Category only return a single row. In that case you need to decide what to show for Category, since more than one row will be condensed down to one. You could still use Max(Category) or Min(Category) and group by, but leave off the having.

select Name, Parent, Max(Category) 
from Table
group by Name, Parent
like image 111
Adam Ruth Avatar answered Oct 01 '22 06:10

Adam Ruth


This query finds all rows where no other row has the same name and parent. If two rows have parent set to NULL, these rows are not considered to have the same parent.

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
like image 27
Mark Byers Avatar answered Oct 01 '22 06:10

Mark Byers


You could use the row_number function to partition by Name and Parent, like:

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

If you're looking to select only rows that are unique, in the sense that no other rows with the same name and parent exist, try:

select *
from YourTable a
where (
    select count(*)
    from YourTable b
    where a.Name = b.Name
    and a.Parent = b.Parent
) = 1
like image 23
Andomar Avatar answered Oct 01 '22 06:10

Andomar


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)

may run slow depending on table size

like image 36
µBio Avatar answered Oct 01 '22 07:10

µBio