Show distinct tuples regardless of column order

纵饮孤独 提交于 2019-12-06 14:19:46

问题


Say I have following results

----------------------
|   col1  |   col2   |
----------------------
|    a    |    b     |
|    b    |    a     |
|    c    |    d     |
|    e    |    f     |
----------------------

I would like to get distinct tuple regardless of column order. In other words, (a, b) and (b, a) are considered "same" because changing the order make one same as the other (a, b) == (a, b). So, after executing query should be:

----------------------
|   col1  |   col2   |
----------------------
|    a    |    b     | // or (b, a)
|    c    |    d     |
|    e    |    f     |
----------------------

Can any query expert help me on this? I've been stuck for few hours and wasn't able to solve this.

Below is my detailed scenario I'm working on.

I have the following relations:

Ships(name, country) // ("Lincoln", "USA") = "Ship Lincoln belongs to USA"
Battles(ship, battleName) // ("Lincoln", "WW2") = "Ship Lincoln fought in WW2"

And I need to find: List all pairs of countries that fought each other in battles

I was able to find all pairs by executing below query:

 SELECT DISTINCT c1, c2
 FROM
 (SELECT DISTINCT s1.country as c1, battleName as b1
  FROM Ships as s1, Battles
  WHERE s1.name = ship) as t1
 JOIN
 (SELECT DISTINCT s2.country as c2, battleName as b2
  FROM Ships as s2, Battles
  WHERE s2.name = ship) as t2
 ON (b1 = b2)
 WHERE c1 <> c2

And the result of executing above query is:

---------------------------------
|       c1      |       c2      |
---------------------------------
|       USA     |     Japan     |   // Row_1
|      Japan    |      USA      |   // Row_2
|     Germany   | Great Britain |   // Row_3
| Great Britain |    Germany    |   // Row_4
---------------------------------

But Row_1 and Row_2 are same as well as Row_3 and Row_4.

What I need is to print either one of Row_1 or Row_2 and either Row_3 or Row_4.

Thank you


回答1:


Try it this way

SELECT DISTINCT
       LEAST(s1.country, s2.country) c1,
       GREATEST(s1.country, s2.country) c2
  FROM battles b1 JOIN battles b2
    ON b1.battlename = b2.battlename
   AND b1.ship <> b2.ship JOIN ships s1
    ON b1.ship = s1.name JOIN ships s2
    ON b2.ship = s2.name
HAVING c1 <> c2

Output:

|      C1 |            C2 |
|---------|---------------|
| Germany | Great Britain |
|   Japan |           USA |

Here is SQLFiddle demo




回答2:


Here is how you can do it

Sample data

| COL1 | COL2 |
|------|------|
|    a |    b |
|    b |    a |
|    c |    d |
|    e |    f |

Query

SELECT
  k.*
FROM test k
  LEFT JOIN (SELECT
               t.col1
             FROM test t
               INNER JOIN test r
                 ON (r.col1 = t.col2
                     AND t.col1 = r.col2)
             LIMIT 1) b
    ON b.col1 = k.col1
WHERE b.col1 IS NULL

OUTPUT

| COL1 | COL2 |
|------|------|
|    a |    b |
|    c |    d |
|    e |    f |

SQL Fiddle Demo




回答3:


That's an interesting question, looks simple but is tricky. I have tried it on SQL Server. Here is my query, assuming input table 'test' contains distinct rows:

| COL1 | COL2 |
|------|------|
|    a |    b |
|    b |    a |
|    c |    d |
|    a |    e |

SELECT t1.col1, t1.col2
FROM test t1
EXCEPT
SELECT t1.col1, t1.col2
FROM test t1
INNER JOIN test t2
ON t1.col1 = t2.col2 AND t1.col2 = t2.col1
AND t1.col1 > t1.col2  

Please replace it with analogous MySQL query if it does not work verbatim. Let me know if this worked for you.



来源:https://stackoverflow.com/questions/21474075/show-distinct-tuples-regardless-of-column-order

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!