Log in

View Full Version : Crisi Mistica : Evidenziare i campi differentu tra due record di tabelle diverse



black
25th November 2010, 14:47
Ho la necessità di evidenziare i campi differenti tra N tabelle rispetto ad 1 tabella "MASTER"

Finche si tratta del confrondo tra 2 tabelle tutto ok, ci sono diversi modi più o meno buoni

SELECT MIN(TableName) as TableName, ID, Testo1, test2
FROM
(
SELECT 'Tabella 1' as TableName, ID, Testo1, test2
FROM [Esercizi].[dbo].[Table_1]

UNION ALL

SELECT 'Tabella 2' as TableName, ID, Testo1, test2
FROM [Esercizi].[dbo].[Table_2]
) tmp

GROUP BY ID, Testo1, Test2
HAVING COUNT(*) = 1
ORDER BY ID, Tablename

Oppure

SELECT [Esercizi].[dbo].[Table_1].Testo1 AS T1_Testo, [Esercizi].[dbo].[Table_2].Testo1 AS T2_Testo, [Esercizi].[dbo].[Table_3].Testo1 AS T3_Testo
FROM [Esercizi].[dbo].[Table_1] INNER JOIN
[Esercizi].[dbo].[Table_3] ON Table_1.ID = Table_3.ID INNER JOIN
[Esercizi].[dbo].[Table_2] ON Table_1.ID = Table_2.ID
WHERE (Table_1.Testo1 <> Table_2.Testo1) OR
(Table_1.Testo1 <> Table_3.Testo1)

Considerando Table1 la master

Cosi a naso mi pare che la prima sia meno "pesante" della seconda (che confronta 2 tabelle con la prima) ma ad occhio non riesco a raffinarla per fare il controllo tra N tabelle e la "master".

Any tricks?

Rise-the-Sky
25th November 2010, 15:17
Per fare una generalizzazione devi usare una subquery..in questo modo tutto quello che devi cambiare è la subquery (che volendo su un sistema reale potrebbe tranquillamente essere una vista) mentre il 'contorno' resta inalterato.

SELECT m.id, m.testo1, m.test2, s.nome_tabella, s.testo1, s.test2
FROM
Esercizi.dbo.Table_1 as m,
(SELECT 'tabella 2' as nome_tabella, testo1, test2
FROM Esercizi.dbo.Table_2
UNION
...
) as s
WHERE m.id = s.id
AND (m.testo1 != s.testo1 OR m.test2 != s.test2)


Nota che questa query funziona solo se si verifica 1 condizione che non ci hai garantito...ovvero che in tutte le tabelle ci siano lo stesso numero di record e con gli stessi ID.
Se questo NON fosse vero non te ne accorgeresti, e per farlo dovresti modificare questa query rendendola una UNION tra questa e 2 sue varianti basate una su una LEFT e una su una RIGHT JOIN (per gestire i 2 casi 'spuri').

PS: ho usato una sintassi diversa perchè sono abiutato a usare quella...l'sql per quanto standard viene 'interpretato' a suo modo da ciascun db.... cmq non penso che avrai problemi solo per qualche differenza banale.

black
25th November 2010, 21:29
innanzi tutto ty,

avevo pensato anche io al problema della left e right join. per cui per ora sto facendo simulazione su 4 dati miei, visto che il db reale lo vedo solo martedi (sigh) quindi come sono fatte nello specifico le tabelle nin lo zo...

stavo cercando di partire "preparato" ad eventuali situazioni critiche.

Ladro di anime
25th November 2010, 22:14
E' tardi, sono rincoglionito, cmq potresti andare di minus, levi dalla prima query tutti i record presenti dalla seconda query.
Se hai dubbi che tra i due gruppi ci possano essere record presenti nel primo e non nel secondo e viceversa vai di due minus piu un union all, cosi da ottenere i record di ognuno dei due gruppi non presenti nell'altro.

black
26th November 2010, 07:55
E' tardi, sono rincoglionito, cmq potresti andare di minus, levi dalla prima query tutti i record presenti dalla seconda query.
Se hai dubbi che tra i due gruppi ci possano essere record presenti nel primo e non nel secondo e viceversa vai di due minus piu un union all, cosi da ottenere i record di ognuno dei due gruppi non presenti nell'altro.

quando siamo entrambi un po piu svegli, vediamo di capire cosa stai dicendo. (oppure mi dai un example banale?) grazie

Ladro di anime
26th November 2010, 09:34
The MINUS query returns all rows in the first query that are not returned in the second query.

Each SQL statement within the MINUS query must have the same number of fields in the result sets with similar data types.

The syntax for an MINUS query is:

select field1, field2, . field_n
from tables
MINUS
select field1, field2, . field_n
from tables;


Example #1

The following is an example of an MINUS query:

select supplier_id
from suppliers
MINUS
select supplier_id
from orders;

In this example, the SQL would return all supplier_id values that are in the suppliers table and not in the orders table. What this means is that if a supplier_id value existed in the suppliers table and also existed in the orders table, the supplier_id value would not appear in this result set.

Rise-the-Sky
26th November 2010, 10:39
Il minus è un opzione valida (anche molto pulita) ma solo se non ti interessa sapere la tabella dove è presente l'incongruenza.

Ovvero io ho la tabella Main, la tabella A e la tabella B

Per id 1 ho che Main e tabella A sono uguali, ma tabella B è differente. Nel result della query troverai la tupla presente nella tabella B, ma nessuna indicazione che la sua origine è B e non A (e se con 2 sole tabelle è poco grave...parlando di N la cosa potrebbe esserlo).
Il problema è risolvibile con subquery ecc.. che operino sul risultato, però si complica la query (e si appesantisce l'esecuzione).

black
26th November 2010, 15:35
se come penso è solo il confronto tra 1 tabella e la master (per N volte diverse) il problema sarebbe infinitamente semplice... appena capisco cosa vogliono di preciso, vedrò di indurstriarmi. per ora tnks