我有一个像这样的选择结果:
from_loc | to_loc |
-------------------------
A | B
------------------------
B | C
------------------------
B | A
------------------------
如何消除表中的重复项,这意味着 A到B 和 B到A 的出现意味着重复。
我正在尝试创建这样的结果,在尝试了几种方法之后我无法解决这个问题......
from_loc | to_loc |
-------------------------
A | B
------------------------
B | C
------------------------
任何人都可以给我一些提示或参考,我怎样才能达到这种效果?
答案 0 :(得分: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);
答案 1 :(得分:1)
也许CASE
中有ROW_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
答案 2 :(得分: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_loc
和to_loc--->to_loc
虽然NOT EXISTS
会消除重复的from_loc-->to_loc
和to_loc-->from_loc
。
答案 3 :(得分: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;
我知道这不是一个有效的解决方案,但它只是有效!