sql,如何消除列间的重复数据

时间:2014-10-19 03:35:12

标签: sql oracle

我有一个像这样的oracle表

customer1    customer2    city
A                B          NY
B                A          NY
A                C          NY
A                D          NY
D                A          NY
C                A          NY

我只对独特的组合感兴趣。

A B或B A等

我需要的输出是

customer1    customer2    city
A                B          NY
A                C          NY
A                D          NY

4 个答案:

答案 0 :(得分:1)

我认为这将满足您的需求。 2个case语句将对这两列进行排序。排序后,您可以获得不同的行。

SELECT DISTINCT
CASE WHEN customer1 < customer2 THEN customer1 ELSE customer2 END customer1,
CASE WHEN customer1 > customer2 THEN customer1 ELSE customer2 END customer2,
city
FROM TABLE

答案 1 :(得分:1)

我们可以通过要求customer1&lt; = customer2来获得一半,但这太限制了。我们需要在custerm1&gt;的情况下加回。 customer2,但不是第一组。只要我们调整列名称,NOT IN运算符就可以在这里工作。

  SELECT c1, c2, city
  FROM t
  HAVING c1 <= c2
UNION
  SELECT c1, c2, city
  FROM t
  WHERE c1 > c2
  AND (c1, c2, city) NOT IN
  (
    SELECT c2 AS c1
         , c1 AS c2
         , city
    FROM t
    WHERE c1 <= c2
  )

在此处查看此操作: http://sqlfiddle.com/#!2/78d1c/23

答案 2 :(得分:1)

我不知道如何将其转换为Oracle(如果可能的话),但Postgres给出了简短的,如果可能效率低下的话

 SELECT DISTINCT ON (LEAST(c1, c2), GREATEST(c1, c2))
   LEAST(c1, c2), GREATEST(c1, c2), city FROM t;

答案 3 :(得分:1)

在Oracle中,您可以这样做:

SELECT DISTINCT LEAST(customer1, customer2),
                GREATEST(customer1, customer2),
                city
FROM T

http://sqlfiddle.com/#!4/b73ba/1
简单易懂。但效率不高(不能使用你的索引)。


如果您需要保留customer1customer2与原始表格中相同的顺序(非重复项),您可能需要更复杂的内容:

SELECT T.* FROM T
JOIN (SELECT MIN(ROWID) RID
      FROM T GROUP BY LEAST(customer1, customer2),
                GREATEST(customer1, customer2),
                city) V
ON T.ROWID = V.RID

或(也许更好):

SELECT T1.* FROM T T1
LEFT JOIN T T2 
ON T1.city = T2.city 
AND T1.customer1 = T2.customer2
AND T1.customer2 = T2.customer1
WHERE T2.city IS NULL OR T1.customer1 < T1.customer2

有关这三种解决方案的比较,请参阅http://sqlfiddle.com/#!4/f7bbd/3