Mysql
 sql >> Database >  >> RDS >> Mysql

Confronto delle righe nella tabella per le differenze tra i campi

Qualsiasi espressione in SQL deve fare riferimento a colonne solo in una riga (escludendo le sottoquery).

Un JOIN può essere utilizzato per creare due righe diverse in una riga del set di risultati.

Quindi puoi confrontare valori su righe diverse eseguendo un'unione automatica. Ecco un esempio che mostra l'unione di ogni riga a ogni altra riga associata allo stesso client (escluso un join di una riga su se stessa):

SELECT c1.*, c2.*
FROM client c1
JOIN client c2 ON (c1.clientID = c2.clientID AND c1.id <> c2.id)

Ora puoi scrivere espressioni che confrontano le colonne. Ad esempio, per limitare la query precedente a quelle in cui field1 è diverso:

SELECT c1.*, c2.*
FROM client c1
JOIN client c2 ON (c1.clientID = c2.clientID AND c1.id <> c2.id)
WHERE c1.field1 <> c2.field1;

Non specifichi che tipo di confronti devi fare, quindi lo lascio a te. Il punto chiave è che, in generale, puoi utilizzare un self-join per confrontare le righe in una determinata tabella.

Riguardo ai tuoi commenti e chiarimenti:Ok, quindi la tua "differenza" non è semplicemente per valore ma per posizione ordinale della riga. Ricorda che i database relazionali non hanno un concetto di numero di riga, hanno solo l'ordine delle righe rispetto a un ordine che devi specificare in un ORDER BY clausola. Non confondere "id " pseudochiave con numero di riga, i numeri vengono assegnati come monotonicamente crescenti solo per coincidenza della loro implementazione.

In MySQL, puoi sfruttare le variabili definite dall'utente per ottenere l'effetto che stai cercando. Ordina la query per clientId e poi da id e tenere traccia dei valori per colonna nelle variabili utente di MySQL. Quando il valore in una riga corrente è diverso dal valore nella variabile, esegui qualsiasi evidenziazione che stavi per fare. Mostrerò un esempio per un campo:

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;

Nota che questa soluzione non è molto diversa dalla semplice selezione di tutte le righe con SQL semplice e dal monitoraggio dei valori con le variabili dell'applicazione durante il recupero delle righe.