Toute expression en SQL ne doit faire référence qu'à des colonnes d'une seule ligne (excluant les sous-requêtes).
Un JOIN
peut être utilisé pour créer deux lignes différentes en une seule ligne du jeu de résultats.
Ainsi, vous pouvez comparer les valeurs sur différentes lignes en effectuant une auto-jointure. Voici un exemple qui montre la jointure de chaque ligne à toutes les autres lignes associées au même client (à l'exception d'une jointure d'une ligne à elle-même) :
SELECT c1.*, c2.*
FROM client c1
JOIN client c2 ON (c1.clientID = c2.clientID AND c1.id <> c2.id)
Vous pouvez maintenant écrire des expressions qui comparent des colonnes. Par exemple, pour limiter la requête ci-dessus à celles où field1 diffère :
SELECT c1.*, c2.*
FROM client c1
JOIN client c2 ON (c1.clientID = c2.clientID AND c1.id <> c2.id)
WHERE c1.field1 <> c2.field1;
Vous ne spécifiez pas les types de comparaisons que vous devez faire, je vous laisse donc cela. Le point clé est qu'en général, vous pouvez utiliser une jointure réflexive pour comparer des lignes dans une table donnée.
Concernant vos commentaires et clarifications :d'accord, donc votre "différence" n'est pas simplement par valeur mais par position ordinale de la ligne. N'oubliez pas que les bases de données relationnelles n'ont pas de concept de numéro de ligne, elles n'ont qu'un ordre de lignes par rapport à un ordre que vous devez spécifier dans un ORDER BY
clause. Ne confondez pas le "id
" pseudo-clé avec numéro de ligne, les numéros sont attribués comme augmentant de manière monotone uniquement par coïncidence de leur mise en œuvre.
Dans MySQL, vous pouvez tirer parti des variables définies par l'utilisateur pour obtenir l'effet recherché. Trier la requête par clientId
puis par id
et suivre les valeurs par colonne dans les variables utilisateur MySQL. Lorsque la valeur d'une ligne actuelle diffère de la valeur de la variable, effectuez la mise en surbrillance que vous alliez faire. Je vais montrer un exemple pour un champ :
SET @clientid = -1, @field1 = '';
SELECT id, clientId, field1, @clientid, @field1,
IF(@clientid <> clientid,
((@clientid := clientid) AND (@field1 := field1)) = NULL,
IF (@field1 <> field1,
(@field1 := field1),
NULL
)
) AS field1_changed
FROM client c
ORDER BY clientId, id;
Notez que cette solution n'est pas vraiment différente de la simple sélection de toutes les lignes avec du SQL brut et du suivi des valeurs avec des variables d'application lorsque vous récupérez des lignes.