2014-07-07 26 views
2

我有一个包含偶数行的表。 这些行形成具有相同信息的对,但交换了前两列的内容 。这里是三列的例子:将行对与交换列组合

1 2 3 
======= 
A B W 
B A W 
C D X 
D C X 
E F Y 
H G Z 
F E Y 
G H Z 

我的实际表具有更多的列,但内容始终是一对在同一个 。

我正在寻找摆脱每对的一行的SQL语句。 结果应该是这样的:

1 2 3 
======= 
A B W 
C D X 
E F Y 
G H Z 

由脚本(我不能改变)生成我的表,所以我想我的 输入正确的是(每行都有一个合作伙伴,行> = 3对每对相同)。 可以检查这些先决条件的声明会非常酷。

+0

哪些DBMS您使用的? Postgres的?甲骨文? –

+0

@a_horse_with_no_name Oracle 11g – bbuser

回答

1

对我来说,下面的代码工作

DECLARE @TEST TABLE 
(A CHAR(1),B CHAR(1),C CHAR(1)) 

INSERT INTO @TEST VALUES 
('A','B','W'), 
('B','A','W'), 
('C','D','X'), 
('D','C','X'), 
('E','F','Y'), 
('H','G','Z'), 
('F','E','Y'), 
('G','H','Z') 

SELECT  MIN(A) [1], 
      MAX(A) [2], 
      C [3] 
FROM  @TEST 
GROUP BY C 

结果:

enter image description here

+1

我发现时间来尝试它,它完美的作品,谢谢[Jithin Sshaji](http://stackoverflow.com/users/3265371/jithin-shaji)。 – bbuser

+0

作出这个接受的答案,因为它是最短的一个工作。还有其他的答案,采取不同的方法,也正确工作。 – bbuser

1

如果每一行都有一个交换对象,其中c1和c2交换,那么只需选择c1和c2按照某个顺序(即c1 < c2)的行。

EXISTS部分确保只显示具有对应项的行。如果要显示所有唯一行,而不管它们是否有对应行,则将最后一个条件从AND EXISTS更改为OR NOT EXISTS

SELECT * FROM myTable t1 
WHERE c1 < c2 
AND EXISTS (
    SELECT * FROM myTable t2 
    WHERE t2.c1 = t1.c2 
    AND t2.c2 = t1.c1 
    AND t2.c3 = t1.c3 
) ORDER BY c1 
+1

工程就像一个魅力,谢谢。 – bbuser

+0

此SQL语句摆脱每对中的一个成员,即使存在重复对也是如此。所以,如果我有两个相同的对前三列的结果将有两行,从这个答案的声明。到目前为止,所有其他答案都只有一行。从我的问题来看,我还不清楚我是否需​​要这个或那个。 – bbuser

1

同样的事情也将有助于使用ROWNUMCTE

with test_Data as 
(
SELECT COL1, COL2, COL3, ROWNUM ROWCOUNT FROM 
(
SELECT 'A' COL1, 'B' COL2, 'W' COL3 FROM DUAL UNION 
SELECT 'B' COL1, 'A' COL2, 'W' COL3 FROM DUAL UNION 
SELECT 'C' COL1, 'D' COL2, 'X' COL3 FROM DUAL UNION 
SELECT 'D' COL1, 'C' COL2, 'X' COL3 FROM DUAL 
) ORDER BY COL3, COL1 
) 
SELECT TAB1.COL1, TAB1.COL2, TAB1.COL3 FROM TEST_DATA TAB1, TEST_DATA TAB2 
WHERE 
TAB1.COL1 = TAB2.COL2 
AND TAB1.COL2 = TAB2.COL1 
AND TAB1.COL3 = TAB2.COL3 
AND TAB1.ROWCOUNT = TAB2.ROWCOUNT+1; 

你的查询,而无需TESTDATA会,

with CTE as 
(SELECT COL1, COL2, COL3, ROWNUM ROWCOUNT FROM MY_TABLE ORDER BY COL3,COL1) 
SELECT TAB1.COL1, TAB1.COL2, TAB1.COL3 FROM CTE TAB1, CTE TAB2 
WHERE 
TAB1.COL1 = TAB2.COL2 
AND TAB1.COL2 = TAB2.COL1 
AND TAB1.COL3 = TAB2.COL3 
AND TAB1.ROWCOUNT = TAB2.ROWCOUNT+1; 
+0

感谢您的努力,我没有尝试这一个,因为来自[FuzzyTree](http://stackoverflow.com/users/)的[更短的解决方案](http://stackoverflow.com/a/24605455/111786) 3574819/fuzzytree)工作。 – bbuser

+0

我有时间尝试一下,它完美的作品,谢谢[Nishanthi Grashia](http://stackoverflow.com/users/3492139/nishanthi-grashia)。 – bbuser

+0

@bbuser:谢谢!乐于帮助!!:-) –

1

你不说出你的DBMS所以这是ANSI SQL:

select least(c1,c2), 
     greatest(c1,c2), 
     min(c3) -- choose min or max to your liking 
from the_table 
group by least(c1,c2), greatest(c1,c2) 
+0

我无法得到这个工作。如果语句正常工作,结果应该只有我的原始表的一半行。这条语句产生的行少得多。 – bbuser

+0

@bbuser:那么对于列c1,c2(从样本数据中看不到的东西),您有两个以上的“重复项”。给你的例子,它产生的正是你所展示的预期输出:http://sqlfiddle.com/#!15/99eee/1 –

+0

我找到时间来尝试一下,它完美的作品,谢谢。我的数据实际上有两个以上的“重复”,你的SQL将它们折叠成一行。 – bbuser