none
Trovare differenze tra due tabelle RRS feed

  • Domanda

  • Salve a tutti, usando sql server 2008 express,e avendo due tabelle con nomi di campi identici, dovrei scrivere un istruzione SQL che mi indichi le righe in cui le due tabelle differiscono.E preferibilmente anche i campi in cui ci sono le differenze...

    Grazie per qualsiasi tipo aiuto :)

    mercoledì 27 luglio 2011 12:30

Tutte le risposte

  • mmm solitamente si immagina differenze fra strutture di tabelle, non nel loro contenuto.

    Cmq la domanda così potrebbe dare una risposta che non ti aiuta molto pochè può essere tutto "diverso"

    Forse ti può andare bene sapere se la chiave primaria (spero tu ne abbia una anche surrogata) di una tabella è contenuta anche nell'altra.

    In questo caso la cosa si risolve semplice con select * from tab1 where pk1 Not in (select pk from tab2)    oppure anche il contrario.

    Se il tuo problema va oltre questo, e vuoi controllare campo per campo, potrebbero essere azzi ...  e non ne vieni più fuori. Perchè poi cosa intendi ? anche un minimo campo del record diverso ?

    brutale brutale, concatena tutto in una stringa (occhio ai null ) e mettici un separatore tipo + '|'  e controlla con lo stesso meccanismo che ti ho scritto sopra

     

     

    mercoledì 27 luglio 2011 13:19
  • Oltre a quanto suggerito da Alessandro, vorrei segnalarti un paio di tools che potrebbero esserti di aiuto nel caso in cui l'operazione di confronto non sia una tantum ma periodica e magari da automatizzare:

    - Red Gate SQL Data Compare (demo per 14 giorni, poi a pagamento)

    - Visual Studio 2010 (Ultimate o Premium) Data Compare tool (compreso nel prodotto)

    HTH


    Danilo Dominici MCP MCDBA MCITP MCSE MCAD ..::.. Questo post è fornito "così com'è". Non conferisce garanzie o diritti di alcun tipo. Ricorda di usare la funzione "segna come risposta" per i post che ti hanno aiutato a risolvere il problema e "deseleziona come risposta" quando le risposte segnate non sono effettivamente utili. Questo è particolarmente utile per altri utenti che leggono il thread, alla ricerca di soluzioni a problemi similari. ENG: This posting is provided "AS IS" with no warranties, and confers no rights. Please remember to click "Mark as Answer" on the post that helps you, and to click "Unmark as Answer" if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
    mercoledì 27 luglio 2011 16:29
  • salve, mi aggiungo ad Alessandro e Danilo, ed oltre a ri-candidare il prodotto Red Gate, dipendentemente dalle tue esigenze, puoi pero' anche eseguire una semplice JOIN tra le tabelle coinvolte.. l'argomento di comunione, quindi il predicato di join, puo' essere esteso a piacimento a tutte o meno le colonne presenti nell'architettura..

    un semplice modo puo' quindi diventare

    SET NOCOUNT ON;
    USE tempdb;
    GO
    CREATE TABLE dbo.t1 (
     [Id] int NOT NULL PRIMARY KEY,
     [varcharCol] [varchar](20) NOT NULL,
     [bitCol] [bit] NOT NULL,
     [dateCol] [date] NOT NULL,
     [decCol] [decimal](18,4) NOT NULL,
     [RowVersion] [timestamp] NOT NULL
     );
    CREATE TABLE dbo.t2 (
     [Id] int NOT NULL PRIMARY KEY,
     [varcharCol] [varchar](20) NOT NULL,
     [bitCol] [bit] NOT NULL,
     [dateCol] [date] NOT NULL,
     [decCol] [decimal](18,4) NOT NULL,
     [RowVersion] [timestamp] NOT NULL
     );

    GO
    SELECT t1.*, t2.*
     -- in caso di valori NULL in una o l'altra parte della proiezione sei in presenza
     -- di una differenza tra t2 e t1
     FROM dbo.t1 t1
      FULL OUTER JOIN dbo.t2 t2
      ON t1.Id = t2.Id AND t1.varcharCol = t2.varcharCol AND t1.decCol = t2.decCol AND t1.bitCol = t2.bitCol AND t1.dateCol = t2.dateCol AND t1.[RowVersion] = t2.[RowVersion]

     WHERE t1.Id IS NULL OR t2.Id IS NULL;
    GO
    DROP TABLE dbo.t1, dbo.t2;

     

    dove il filtro di WHERE sul FULL JOIN proiettera' le sole righe nelle quali sia presente una differenza, dove quindi la JOIN produrra' un risultato NULL per una o l'altra tabella coinvolta nell'esplosione di join... ovvio che questo puo' non considerarsi uno strumento paritetico a quello commerciale indicato, ma talvolta puo' anche essere sufficiente dipendentemente dalle esigenze..

    saluti


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/
    mercoledì 27 luglio 2011 22:58
    Moderatore
  • Ciao Andrea,

    l'esempio che riporti è carino ma quella query specifica restituirà sempre tutte le righe di t1 e t2. Cioè quel ON è sempre e solo falso. Se così in fosse Sql starebbe commettendo un grave errore avendo generato due timestamp uguali nel medesimo database.

    marc.

    giovedì 28 luglio 2011 13:00
  • salve Marc,

    cosi' imparo a fare "copy & paste" dal mio SSMS :)

    grazie per la correzione..

    saluti e baci


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/
    giovedì 28 luglio 2011 17:30
    Moderatore
  • Ciao Nikky,

    la domanda è etremamente più insidiosa di quanto si possa immaginare. Il caso più generale possibile è quello di una tabella senza chiavi di alcun tipo e in questa situazione è davvero arduo procedere rapidamente per il raggiungimento del risultato. 

    Se le tabelle o in (generale le query) di base hanno un qualche tipo di chiave puoi ottenere le ennuple di t1 non presenti in t2 con:

     

    select * from t1
    except
    select * from t2
    

     

    Osserva come la presenza di una chiave garantisca che l'opzione distinct implicita nell'operatore except non generi casi anomali. Viceversa ottieni le ennuple di t2 non presenti in t1 con:

     

    select * from t2
    except
    select * from t1
    

     

    Se le tabelle non contengono alcuna chiave potremmo affermare che le tabelle coincidono se le stesse ennuple appaiono lo stesso numero di volte e quindi, in generale:

     

    select c1, c2, ..., cn, C=count(*) from t1 group by c1, c2, ..., cn
    except
    select c1, c2, ..., cn, C=count(*) from t2 group by c1, c2, ..., cn

     

    marc.

     


    venerdì 29 luglio 2011 12:43