8

我正在尝试根据混合列查找重复的行。这是我所拥有的一个例子:

CREATE TABLE Test
(
   id INT PRIMARY KEY,
   test1 varchar(124),
   test2 varchar(124)
)

INSERT INTO TEST ( id, test1, test2 ) VALUES ( 1, 'A', 'B' )
INSERT INTO TEST ( id, test1, test2 ) VALUES ( 2, 'B', 'C' )

现在如果我运行这个查询:

SELECT [LEFT].[ID] 
FROM [TEST] AS [LEFT] 
   INNER JOIN [TEST] AS [RIGHT] 
   ON [LEFT].[ID] != [RIGHT].[ID] 
WHERE [LEFT].[TEST1] = [RIGHT].[TEST2]

我希望能取回两个身份证。(1和2),但是我只拿回一排。

我的想法是它应该比较每一行,但我想这是不正确的?为了解决这个问题,我将查询更改为:

SELECT [LEFT].[ID] 
FROM [TEST] AS [LEFT] 
   INNER JOIN [TEST] AS [RIGHT] 
   ON [LEFT].[ID] != [RIGHT].[ID] 
WHERE [LEFT].[TEST1] = [RIGHT].[TEST2] 
OR [LEFT].[TEST2] = [RIGHT].[TEST1]

这给了我两行,但是根据行数,性能会迅速下降。

我为性能和结果提出的最终解决方案是使用联合:

SELECT [LEFT].[ID] 
FROM [TEST] AS [LEFT] 
   INNER JOIN [TEST] AS [RIGHT] 
   ON [LEFT].[ID] != [RIGHT].[ID] 
WHERE [LEFT].[TEST1] = [RIGHT].[TEST2] 
UNION
SELECT [LEFT].[ID] 
FROM [TEST] AS [LEFT] 
   INNER JOIN [TEST] AS [RIGHT] 
   ON [LEFT].[ID] != [RIGHT].[ID] 
WHERE [LEFT].[TEST2] = [RIGHT].[TEST1]

但总的来说,我显然不明白为什么这不起作用,这意味着我可能做错了什么。有人能指出我正确的方向吗?

4

4 回答 4

11

不要加入不等式;似乎 JOIN 和 WHERE 条件是相反的。

SELECT t1.id
FROM Test t1
INNER JOIN Test t2
ON ((t1.test1 = t2.test2) OR (t1.test2 = t2.test1))
WHERE t1.id <> t2.id

应该可以正常工作。

于 2009-12-11T19:47:07.350 回答
6

如果您选择它们​​,您只能取回两个 id:

SELECT [LEFT].[ID], [RIGHT].[ID] 
FROM [TEST] AS [LEFT] 
   INNER JOIN [TEST] AS [RIGHT] 
   ON [LEFT].[ID] != [RIGHT].[ID] 
WHERE [LEFT].[TEST1] = [RIGHT].[TEST2]

只得到一个 ROW 的原因是只有一行(即第 2 行)的 TEST1 等于另一行的 TEST2。

于 2009-12-11T19:48:09.563 回答
2

我看起来你正在为Cartiesian Join快速工作。通常,如果您要返回重复项,则需要运行以下命令:

SELECT [LEFT].*
FROM [TEST]  AS [LEFT]
INNER JOIN [TEST] AS [RIGHT]
    ON [LEFT].[test1] = [RIGHT].[test1]
        AND [LEFT].[test2] = [RIGHT].[test2]
        AND [LEFT].[id] <> [RIGHT].[id]

如果您需要混合列,则混合所需的条件,但执行以下操作:

SELECT [LEFT].*
FROM [TEST] AS [LEFT]
INNER JOIN [TEST] AS [RIGHT]
    ON (
        [LEFT].[test1] = [RIGHT].[test2]
            OR [LEFT].[test2] = [RIGHT].[test1]
       )
        AND [LEFT].[id] <> [RIGHT].[id]

使用它,您可以在每个连接中比较右到左和左到右,完全消除了对 WHERE 的需要。

但是,这种查询方式在插入到表中的每一行的执行时间上呈指数增长,因为您正在将每一行与每一行进行比较。

于 2009-12-11T19:53:37.897 回答
0

如果我没记错的话,这可以不用内部连接来完成。这是我第一次回答 mysql 类的问题,但我只是在 StackOverflow 上回答以获得更多积分。逗号非常重要,这样mysql就不会抱怨。

SELECT [LEFT].[ID] FROM [TEST] AS [LEFT], [TEST] AS [RIGHT] 
WHERE [LEFT].[ID] != [RIGHT].[ID] 
AND [LEFT].[TEST1] = [RIGHT].[TEST2];
于 2012-12-01T18:53:04.180 回答