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.
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.
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
)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With