Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eliminate rows with columns with inverted values

I am having so much trouble trying to work this out. Can somebody help me?

I have a table with colA and colB and these as the values for each row:

colA  ColB
2     1
1     2

When selecting in this table, I want to retrieve just one row since the values are inverted. If 2 implies 1, 1 implies 2, so they are equal and I don't want two rows as a return.

Is there any way of doing a SQL query and get the result I want? For example, just one row with colA = 1, colB = 2.

like image 664
guimellon Avatar asked Oct 31 '14 19:10

guimellon


3 Answers

If it is only 2 columns:

WITH t(colA, colB) AS (
    VALUES (1,2), (2,1)
)
SELECT DISTINCT least(colA, colB), greatest(colA, colB)
  FROM t;

EDIT: As outlined by Daniel, although this might do the job, this approach is not good for filtering as it'll change the original data.

like image 175
vyegorov Avatar answered Oct 15 '22 11:10

vyegorov


No indication was made as to which version of the tuple is preferred over the other. I.e., we know that (1,2) is equivalent to (2,1) and in that case one of the two should be display, but which of the two? In this solution, the assumption is that the variant with the lower ColA value is preferred over the reverse.

Select ColA, ColB
From SourceData As S
Where ColA < ColB
    Or Not Exists   (
                    Select 1
                    From SourceData As S1
                    Where S1.ColA = S.ColB
                        And S1.ColB = S.ColA
                    )
like image 3
Thomas Avatar answered Oct 15 '22 13:10

Thomas


The SQL SELECT ... EXCEPT SELECT ... construct may be used for this. Also it will probably be faster than queries involving a self-join, especially without any index. I would suggest:

SELECT colA, colB FROM table
  EXCEPT
SELECT colB, colA FROM table WHERE colA < colB;

Duplicates rows are eliminated (if not needed or not desirable, use EXCEPT ALL).

Rows where colA=colB are not a special case, they go into the result, de-duplicated.

like image 3
Daniel Vérité Avatar answered Oct 15 '22 11:10

Daniel Vérité