无论列顺序如何,都显示不同的元组

时间:2014-01-31 06:47:02

标签: mysql sql distinct

说我有以下结果

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

无论列顺序如何,我都希望得到明显的元组。换句话说,(a,b)和(b,a)被认为是“相同的”,因为改变顺序使得一个与另一个相同(a,b)==(a,b)。所以,执行查询后应该是:

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

任何查询专家都可以帮我吗?我已经被困了几个小时而且无法解决这个问题。

以下是我正在制作的详细方案。

我有以下关系:

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

我需要找到:列出在战斗中互相争斗的所有国家/地区

我能够通过执行以下查询找到所有对:

 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

执行上述查询的结果是:

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

但Row_1和Row_2与Row_3和Row_4相同。

我需要的是打印Row_1或Row_2以及Row_3或Row_4中的任何一个。

谢谢

3 个答案:

答案 0 :(得分:2)

以这种方式试试

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

输出:

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

这是 SQLFiddle 演示

答案 1 :(得分:0)

以下是如何做到这一点

示例数据

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

查询

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

输出

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

SQL Fiddle Demo

答案 2 :(得分:0)

这是一个有趣的问题,看起来很简单但很棘手。我在SQL Server上试了一下。这是我的查询,假设输入表'test'包含不同的行:

| 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  

如果它不是逐字的,请用类似的MySQL查询替换它。如果这对您有用,请告诉我。