user1578460
user1578460

Reputation: 315

Exclude same pairs from sql query

I have a table that has two columns in it:

primId   column1   column2
1         98        62
2         62        98
3         3         105
4         105       3
5         11        4

I need to get second row, fourth row, fifth row. if 98,62 has appeared once then 62,98 cannot appear (if possible I need latest value). I have taken help from this link Removing Mirrored Pairs from SQL Join, but got no luck. These values are not related to each other in greater or lesser. Please let me know how I can get this result. Is this possible with Sql query. Thanks

Upvotes: 1

Views: 1682

Answers (4)

Stefano Zanini
Stefano Zanini

Reputation: 5926

You can do it this way:

select  t1.*
from    yourTable t1
left join
        yourTable t2
on      t1.column1 = t2.column2 and
        t1.column2 = t2.column1
where   t2.column1 is null or
        t1.column1 > t1.column2

The mirrored rows will be joined, and you will only take them once due to the second where condition, and the rows that are not mirrored will not be joined, so you'll get them with the first where condition.

Edit

To have the last couple returned, you can use this approach instead

select  t1.*
from    yourTable t1
join    (
            select  max(primId) as primId,
                    case when column1 > column2 then column2 else column1 end c1,
                    case when column1 < column2 then column2 else column1 end c2
            from    yourTable
            group by case when column1 > column2 then column2 else column1 end,
                     case when column1 < column2 then column2 else column1 end
        ) t2
on      t1.primId = t2.primId

The inner query will return the highest primId for each couple, regardless of the order. Joining it with the source table, you use it as a filter.

You can see it working here

Upvotes: 3

Gordon Linoff
Gordon Linoff

Reputation: 1271231

If you want to ensure that you keep the original pairs (so 4,1 would not be allowed as output), then the following should be very efficient:

select t.*
from t
where t.column1 <= t.column2
union all
select t.*
from t
where t.column1 > t.column2 and
      not exists (select 1 from t t2 where t2.column1 = t.column2 and t2.column2 = t.column1);

For optimal performance, you want an index on t(column1, column2).

Upvotes: 0

Vamsi Prabhala
Vamsi Prabhala

Reputation: 49270

When it doesn't matter if the row in the result-set of the query exists in the table, you can use least and greatest so that one row per pair is retrieved.

select distinct least(column1,column2) as col1, greatest(column1,column2) as col2 
from tablename

If the row retrieved has to be present in the table, use the previous query and join it to the existing table.

select t.column1,t.column2
from tablename t
left join (select least(column1,column2) as col1, greatest(column1,column2) as col2 
           from tablename
           group by least(column1,column2), greatest(column1,column2)
           having count(*)>1
          ) x on x.col1=t.column1 and x.col2=t.column2
where x.col1 is null and x.col2 is null

Upvotes: 0

Giorgos Betsos
Giorgos Betsos

Reputation: 72235

You can use the following query:

SELECT DISTINCT LEAST(column1, column2) AS column1,
                GREATEST(column1, column2) AS column2
FROM mytable

Note: The above query works provided the field order is irrelevant to you. Otherwise you have to use a JOIN like @Stefano proposes.

Upvotes: 0

Related Questions