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]

私は両方のIDを取り戻すことを期待しています。(1と2)しかし、私は1行しか取り戻せません。

私の考えでは、各行を比較する必要がありますが、これは正しくないと思いますか?これを修正するために、クエリを次のように変更しました。

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を選択した場合にのみ、両方の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]

1つの行だけを取得する理由は、1つの行(つまり行#2)だけが別の行のTEST2と等しいTEST1を持っているためです。

于 2009-12-11T19:48:09.563 に答える
2

CartiesianJoinに向けて非常に迅速に取り組んでいるようです。通常、重複を返す場合は、次のようなものを実行する必要があります。

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 に答える