7

我有一个有两列的表:

  1. person_id
  2. 与第一个字段 id 合作的 person_id

我需要选择所有合作对,这很容易,但问题出在哪里:表中的数据如下:987- 102, 103 - 104, 104 - 103, 21 - 102。由于这些数据的结果我应该有 3 个合作对987 - 102, 103-104, 21-102, 正如你所看到的103 - 104,并且104 - 103记录具有相同的逻辑,我怎样才能避免它们的重复。任何的想法?

谢谢,最好的问候。安东。

4

2 回答 2

10

您可以使用 MySQL 的LEAST()GREATEST()函数,以及DISTINCT

SELECT DISTINCT LEAST(a, b), GREATEST(a, b) FROM mytable
于 2012-07-02T17:59:01.787 回答
3

如果保留每个“对”中元素的顺序并不重要,请参阅 eggyal 的答案。该查询返回的结果集与您指定的结果集略有不同,它返回 pair102-987而不是987-102. 它还消除了表格中出现的任何“重复”对。

如果保留每对中元素的顺序重要,并且当这两个“匹配”对都存在时,您希望返回“更小 - 更大”而不是“更大 - 更小”,则可以使用以下内容:

SELECT c.col1, c.col2
  FROM mytable c
  LEFT
  JOIN mytable d ON d.col1 = c.col2 AND d.col2 = c.col1 AND d.col1 <> d.col2
 WHERE (d.col1 IS NULL OR d.col1 > c.col1)

要消除所有重复对和“匹配”对,请添加 GROUP BY 子句或 DISTINCT 关键字,例如

SELECT c.col1, c.col2
  FROM mytable c
  LEFT
  JOIN mytable d ON d.col1 = c.col2 AND d.col2 = c.col1 AND d.col1 <> d.col2
 WHERE (d.col1 IS NULL OR d.col1 > c.col1)
 GROUP BY c.col1, c.col2

笔记:

SQL 小提琴在这里:http ://sqlfiddle.com/#!2/1d9e7/1 在这里: http : //sqlfiddle.com/#!2/1d9e7/2

比较运算符不是 null 安全的,当 col1 或 col2 包含 NULL 值时,它们可能不会返回您想要的结果集。(可以修改查询以处理 col1 和/或 col2 的 NULL 值。)如所写,两个查询都将返回,例如,(1,NULL)如果(NULL,1)这些“匹配”“对”在表中,则返回。(归结为您是否要考虑匹配 NULL 值的问题。)

另请注意,两个查询都将返回行 where col1=col2

请注意,第一个查询不会消除表中存在的“重复”行。也就是说,如果重复的“对”例如(202,101)出现在两个不同的行中,则两者都将被返回(除非查询返回至少一个具有“匹配”对的行:(101,202)。)

不清楚在这些情况下您希望返回什么结果集,因此第一个查询显示了(larger,smaller)当匹配(smaller,larger)对位于结果集中时仅消除行的模式。

第二个查询消除了所有重复和“匹配”对。

于 2012-07-02T18:51:44.387 回答