Question

Je suis en train de trouver des lignes en double sur la base des colonnes mixtes. Ceci est un exemple de ce que j'ai:

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' )

Maintenant, si je lance cette requête:

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

Je me attends à revenir deux identifiants. (1 et 2), mais je ne reçois que jamais de retour d'une ligne.

Mes pensées seraient qu'il devrait comparer chaque ligne, mais je suppose que cela est pas correcte? Pour résoudre ce problème, je l'avais changé ma requête à:

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]

Ce qui me donne les deux lignes, mais la performance se dégrade très rapidement en fonction du nombre de lignes.

La solution finale, je suis venu pour la performance et les résultats était d'utiliser une union:

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]

Mais dans l'ensemble, je manque évidemment de comprendre pourquoi cela ne fonctionne pas ce qui veut dire que je fais sans doute quelque chose de mal. Quelqu'un pourrait-il me diriger dans la bonne direction?

Était-ce utile?

La solution

Ne pas JOIN sur une inégalité; il semble que le JOIN et les conditions WHERE sont inversées.

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

devrait fonctionner correctement.

Autres conseils

Vous ne reçoivent que deux identifiants si vous les sélectionnez:

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

La raison pour laquelle obtenir une seule ligne est qu'une seule ligne (à savoir rangée # 2) a une TEST1 égale à une autre ligne de TEST2.

Je regarde comme vous travaillez très rapidement vers un Cartiesian Rejoignez . En règle générale, si vous cherchez à retourner les doublons, vous devez exécuter quelque chose comme:

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]

Si vous avez besoin de mélanger les colonnes, puis mélanger les conditions nécessaires, mais faire quelque chose comme:

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]

L'utilisation que vous comparez le droit à gauche et de gauche à droite dans chaque jointure, ce qui élimine la nécessité de WHERE tout à fait.

Cependant, ce style de requête croît de façon exponentielle dans le temps d'exécution pour chaque ligne insérée dans la table, puisque vous comparez chaque ligne à chaque ligne.

Cela peut être fait avec des jointures si je ne me trompe pas. Ce première fois que répondre mysql genre de question, mais je suis en train de répondre pour obtenir plus de points ici sur StackOverflow. La virgule est très important pour que MySQL ne se plaint pas.

SELECT [LEFT].[ID] FROM [TEST] AS [LEFT], [TEST] AS [RIGHT] 
WHERE [LEFT].[ID] != [RIGHT].[ID] 
AND [LEFT].[TEST1] = [RIGHT].[TEST2];
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top