2013-11-28 35 views
2

重复组合我有一个选择结果是这样的:消除从结果

from_loc | to_loc | 
------------------------- 
A   | B 
------------------------ 
B   | C 
------------------------ 
B   | A 
------------------------ 

怎样消除从这意味着A的发生到BB到A装置复制表重复。

我想这样创造的结果,试图对夫妇的方式我没能解决这个问题后...

from_loc | to_loc | 
------------------------- 
A   | B 
------------------------ 
B   | C 
------------------------ 

任何人都可以给我一些提示或参考我如何能达到这种结果?

+0

发布您当前的SQL查询 – Shai

+0

嗨,谢谢,我的查询真的很大,我只是为了让它理解而放在这里非常简化的场景。谢谢! – user1143343

回答

2

我没有测试过这个解决方案,但它可能有更好的表现(较少的逻辑读):

DECLARE @MyTable TABLE 
(
    from_loc VARCHAR(100) NOT NULL, 
    to_loc VARCHAR(100) NOT NULL 
); 
INSERT @MyTable (from_loc, to_loc) VALUES ('A', 'B'); 
INSERT @MyTable (from_loc, to_loc) VALUES ('B', 'C'); 
INSERT @MyTable (from_loc, to_loc) VALUES ('B', 'A'); 

SELECT DISTINCT src.from_loc_new, src.to_loc_new 
FROM 
(
SELECT CASE WHEN x.from_loc <= x.to_loc THEN x.from_loc ELSE x.to_loc END AS from_loc_new, 
     CASE WHEN x.from_loc <= x.to_loc THEN x.to_loc ELSE x.from_loc END AS to_loc_new 
FROM @MyTable x 
) src 
-- You could also test these query hints to see if there is a better performance 
-- OPTION (HASH GROUP) 
-- or 
-- OPTION (ORDER GROUP); 
+0

如果只有一个有值的记录('D','C'),会发生什么?这个SQL会将它转换为('C','D'),对吧?这是你想要的吗? –

+0

@OchiWansa:2&3)是的。 –

0

尝试DISTINCT然后NOT EXISTS,如:

SELECT DISTINCT from_loc, to_loc 
FROM TableName A 
WHERE NOT EXISTS 
(
    SELECT from_loc, to_loc 
    FROM TableName B 
    WHERE A.from_loc = B.to_loc 
    AND A.to_loc = B.from_loc 
) 

DISTINCT将消除重复from_loc-->from_locto_loc--->to_locNOT EXISTS将消除重复from_loc-->to_locto_loc-->from_loc

+0

这将摆脱副本的两个副本,即删除'A | B' **和**'B | A'。问题需要这两行中的一行保留 – Shai

1
与此

也许CASEROW_NUMBER

WITH CTE AS( 
    SELECT from_loc, to_loc, 
     rn = row_Number() Over (Partition By CASE WHEN from_loc > to_loc 
            Then to_loc + '|' + from_loc 
            Else from_loc + '|' + to_loc END 
           Order By from_loc, to_loc) 
    FROM dbo.TableName 
) 
SELECT from_loc, to_loc FROM cte WHERE rn = 1 

Demo

0

假设您的原始SQL是:

SELECT from_loc, to_loc FROM route; 

使用它两次作为与LEFT JOIN连接在一起的子查询。之后,使用IF明确选择所需的字段。

SELECT DISTINCT 
    IF (y.from_loc IS NULL, x.from_loc, 
    IF(x.from_loc < x.to_loc, x.from_loc, x.to_loc)) AS from_loc, 
    IF (y.from_loc IS NULL, x.to_loc, 
    IF(x.from_loc > x.to_loc, x.from_loc, x.to_loc)) AS to_loc 
FROM (
) AS x 
    SELECT from_loc, to_loc FROM route 
LEFT JOIN (
    SELECT from_loc, to_loc FROM route 
) AS y 
ON x.from_loc = y.to_loc AND x.to_loc = y.from_loc; 

对于演示中,我使用下面的SQL在你的问题,以创建示例数据:

SELECT "A" AS from_loc, "B" AS to_loc 
UNION SELECT "B", "C" 
UNION SELECT "B", "A"; 

试试这个在您的MySQL客户端应用程序:

SELECT DISTINCT 
    IF (y.from_loc IS NULL, x.from_loc, 
    IF(x.from_loc < x.to_loc, x.from_loc, x.to_loc)) AS from_loc, 
    IF (y.from_loc IS NULL, x.to_loc, 
    IF(x.from_loc > x.to_loc, x.from_loc, x.to_loc)) AS to_loc 
FROM (
) AS x 
    SELECT "A" AS from_loc, "B" AS to_loc 
    UNION SELECT "B", "C" 
    UNION SELECT "B", "A" 
LEFT JOIN (
    SELECT "A" AS from_loc, "B" AS to_loc 
    UNION SELECT "B", "C" 
    UNION SELECT "B", "A" 
) AS y 
ON x.from_loc = y.to_loc AND x.to_loc = y.from_loc; 

我知道这是不是一个有效的解决方案,但它只是起作用!

+0

哦,我很抱歉,我以为你在使用MySQL ... –