tabellen vergelijken

Status
Niet open voor verdere reacties.

anlag1

Gebruiker
Lid geworden
31 okt 2010
Berichten
144
Dag allemaal,

2 tabellen, A en B. bijvoorbeeld ieder met een kolom met cijfers.

A B

1 3
2 8
8 7
3 9
9 6

Nu zou ik graag een query maken met onderstaand resultaat

1 -
2 -
3 3
- 6
- 7
8 8
9 9

wie kan mij helpen?
Gr,
André
 
Met een Union Query kom je een heel eind.
Code:
SELECT A.A, IIf([b] Is Null,"-",[b]) AS C FROM A LEFT JOIN B ON A.A = B.B ORDER BY A.A
UNION
SELECT IIf([a] Is Null,"-",[a]) AS C, B.B FROM B LEFT JOIN A ON B.B = A.A
 
Dank je wel, werkt perfect.:thumb:
Stel nu dat beide tabellen A & B meerdere velden hebben die allen moeten worden vergeleken?
bijv. A,B,C en D, wat zou dan de sql routine worden? m.n. de left join begrijp ik dan niet
Gr.
Andre
 
Normaal gesproken maak je een query met een INNER JOIN. Dat houdt in: alleen records laten zien waarvan de gekoppelde velden in beide tabellen overeenkomen. Dus een query met PersoonID in Personen en PersoonID in Bestellingen geeft met een Inner Join alleen klanten weer die iets besteld hebben. Wil je alle klanten zien en per klant het aantal bestellingen, dan heb je niks aan een Inner Join, en maak je een Left Join (of een Right Join, afhankelijk van de inrichting kan dat wisselen). Daarmee zie je van één tabel alle records, en van de andere tabel de gekoppelde gegevens.
In het gevanl van de klanten zie je dus bij klanten die nog niks besteld hebben geen waarde (of een - zoals in jouw vraag m.b.v. de IIF) en bij de klanten met bestellingen (bijvoorbeeld) het aantal bestellingen. Zou je in dit voorbeeld de Join omdraaien (Alle bestellingen en gekoppelde klanten) dan is het resultaat gelijk aan de Inner Join, omdat er geen records zijn (als het goed is) van klanten die niet in de klantentabel staan.

Wil je matchen op meerdere velden, dan kan dat uiteraard wel, maar dan wordt je Join wat uitgebreider. En wellicht wil je dan ook meer kolommen zien, dus die constructie moet je dan ook uitbouwen.
Kom je er niet uit, maak dan een voorbeeldje, want ik ben nét iets te lelijk om als tikpoes te kunnen werken ;). Bovendien is data inkloppen bepaald niet mijn grootste hobby...
 
Michel,

Dank voor de uitleg, :thumb: heb elke tabel 8 velden gegeven
Onderstaande routine werkt prima, daar een samenvoegquery alleen in sql weergave gemaakt kan worden is het wel een tijdrovend klusje.
duurde even vanwege tikfouten, maar goed, gezien het resultaat is dat al snel vergeten
Gr,
André


Code:
SELECT A.A,A.B,A.C,A.D,A.E,A.F,A.G,A.H,
IIf([B.A] Is Null,"-",[B.A]) AS K,
IIf([B.B] Is Null,"-",[B.B]) AS L,
IIf([B.C] Is Null,"-",[B.C]) AS M,
IIf([B.D] Is Null,"-",[B.D]) AS N,
IIf([B.E] Is Null,"-",[B.E]) AS P,
IIf([B.F] Is Null,"-",[B.F]) AS R,
IIf([B.G] Is Null,"-",[B.G]) AS S,
IIf([B.H] Is Null,"-",[B.H]) AS T
FROM A LEFT JOIN B ON A.A = B.A AND A.B = B.B AND A.C = B.C AND A.D = B.D AND A.E = B.E AND A.F = B.F AND A.G = B.G AND A.H = B.H ORDER BY A.A
UNION SELECT
IIf([A.A] Is Null,"-",[A.A]) AS K,
IIf([A.B] Is Null,"-",[A.B]) AS L,
IIf([A.C] Is Null,"-",[A.C]) AS M,
IIf([A.D] Is Null,"-",[A.D]) AS N,
IIf([A.E] Is Null,"-",[A.E]) AS P,
IIf([A.F] Is Null,"-",[A.F]) AS R,
IIf([A.G] Is Null,"-",[A.G]) AS S,
IIf([A.H] Is Null,"-",[A.H]) AS T,
B.A, B.B, B.C, B.D, B.E, B.F, B.G, B.H FROM B LEFT JOIN A ON B.A = A.A AND B.B = A.B AND B.C = A.C AND B.D = A.D AND B.E = A.E AND B.F = A.F AND B.G = A.G AND B.H = A.H;
 
Dat kloppen van de SQL in een UNION kun je nog enigszins beperken door de eerste query te maken op de gebruikelijke manier, die code te kopieëren en te plakken onder de eerste code. Uiteraard typ je er dan eerst UNION tussen :).
De tweede code pas je dan aan als dat nodig is. Ben je met minimaal typwerk klaar Al is dit wel goed voor je vingervlugheid :D
 
met de huidige routine krijg je alles terug, als je nu alleen de verschillen wilt hebben moet er waarschijnlijk een WHERE-component bij.
maar waar moet die dan geplaatst worden en met welke voorwaarden?
Gr,
André :confused:
 
Ik snap niet wat je bedoelt. Maar met een db-voorbeeld wordt het vast duidelijker :)
 
In het voorbeeldje zit een query ABCKLM, hierin worden 2 records getoond die voldoen aan ABC=KLM
Deze 2 records wil ik niet zien zodat alleen ABC<>KLM overblijft.
André

Bekijk bijlage db_union.rar
 
Jij houdt van simpele oplossingen :). Je zult de waarden weg moeten halen uit het resultaat met een subquery. In jouw voorbeeld wordt de SQL dan:
Code:
SELECT A.A,A.B,A.C, IIf([B.A] Is Null,"-",[B.A]) AS K, IIf([B.B] Is Null,"-",[B.B]) AS L, IIf([B.C] Is Null,"-",[B.C]) AS M 
FROM A LEFT JOIN B ON A.A = B.A AND A.B = B.B AND A.C = B.C 
WHERE (
     	([A].[A] Not In (SELECT A.A FROM A INNER JOIN B ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C)) Or (A.A) Is Null) 
     	AND ([A].[B] Not In (SELECT A.B FROM A INNER JOIN B ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C)) Or (A.B) Is Null) 
     	AND ([A].[C] Not In (SELECT A.C FROM A INNER JOIN B ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C)) Or (A.C) Is Null)
	)
ORDER BY A.A
UNION 
SELECT IIf([A.A] Is Null,"-",[A.A]) AS K, IIf([A.B] Is Null,"-",[A.B]) AS L, IIf([A.C] Is Null,"-",[A.C]) AS M, B.A, B.B, B.C 
FROM B LEFT JOIN A ON B.A = A.A AND B.B = A.B AND B.C = A.C
WHERE (
	([B].[A] Not In (SELECT B.A FROM B INNER JOIN A ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C)) Or (B.A) Is Null) 
     	AND ([B].[B] Not In (SELECT B.B FROM B INNER JOIN A ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C)) Or (B.B) Is Null) 
     	AND ([B].[C] Not In (SELECT B.C FROM B INNER JOIN A ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C)) Or (B.C) Is Null)
	)
 
Hoe krijg je het verzonnen.
Heb jou code aangepast en toegevoegd aan de reeds eerder getoonde code voor tabellen met 8 velden
Maar nu heb ik een lege query als resultaat
Wat doe ik verkeerd? :shocked:

Code:
SELECT A.A,A.B,A.C,A.D,A.E,A.F,A.G,A.H,
IIf([B.A] Is Null,"-",[B.A]) AS K,
IIf([B.B] Is Null,"-",[B.B]) AS L,
IIf([B.C] Is Null,"-",[B.C]) AS M,
IIf([B.D] Is Null,"-",[B.D]) AS N,
IIf([B.E] Is Null,"-",[B.E]) AS P,
IIf([B.F] Is Null,"-",[B.F]) AS R,
IIf([B.G] Is Null,"-",[B.G]) AS S,
IIf([B.H] Is Null,"-",[B.H]) AS T
FROM A LEFT JOIN B ON A.A = B.A AND A.B = B.B AND A.C = B.C AND A.D = B.D AND A.E = B.E AND A.F = B.F AND A.G = B.G AND A.H = B.H 
WHERE (
([A].[A] Not In (SELECT A.A FROM A INNER JOIN B ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (A.A) Is Null) 
	AND ([A].[B] Not In (SELECT A.B FROM A INNER JOIN B ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (A.B) Is Null) 
	AND ([A].[C] Not In (SELECT A.C FROM A INNER JOIN B ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (A.C) Is Null)
	AND ([A].[D] Not In (SELECT A.D FROM A INNER JOIN B ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (A.D) Is Null)
	AND ([A].[E] Not In (SELECT A.E FROM A INNER JOIN B ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (A.E) Is Null)
	AND ([A].[F] Not In (SELECT A.F FROM A INNER JOIN B ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (A.F) Is Null)
AND ([A].[G] Not In (SELECT A.G FROM A INNER JOIN B ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (A.G) Is Null)
	)
ORDER BY A.A
UNION SELECT
IIf([A.A] Is Null,"-",[A.A]) AS K,
IIf([A.B] Is Null,"-",[A.B]) AS L,
IIf([A.C] Is Null,"-",[A.C]) AS M,
IIf([A.D] Is Null,"-",[A.D]) AS N,
IIf([A.E] Is Null,"-",[A.E]) AS P,
IIf([A.F] Is Null,"-",[A.F]) AS R,
IIf([A.G] Is Null,"-",[A.G]) AS S,
IIf([A.H] Is Null,"-",[A.H]) AS T,
B.A, B.B, B.C, B.D, B.E, B.F, B.G, B.H
FROM B LEFT JOIN A ON B.A = A.A AND B.B = A.B AND B.C = A.C AND B.D = A.D AND B.E = A.E AND B.F = A.F AND B.G = A.G AND B.H = A.H
WHERE (
([B].[A] Not In (SELECT B.A FROM B INNER JOIN A ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (B.A) Is Null) 
	AND ([B].[B] Not In (SELECT B.B FROM B INNER JOIN A ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (B.B) Is Null) 
	AND ([B].[C] Not In (SELECT B.C FROM B INNER JOIN A ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (B.C) Is Null)
	AND ([B].[D] Not In (SELECT B.D FROM B INNER JOIN A ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (B.D) Is Null)
	AND ([B].[E] Not In (SELECT B.E FROM B INNER JOIN A ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (B.E) Is Null)
	AND ([B].[F] Not In (SELECT B.F FROM B INNER JOIN A ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (B.F) Is Null)
AND ([B].[G] Not In (SELECT B.G FROM B INNER JOIN A ON (A.A = B.A) AND (A.B = B.B) AND (A.C = B.C) AND (A.D = B.D) AND (A.E = B.E) AND (A.F = B.F) AND (A.G = B.G) AND (A.H = B.H)) Or (B.G) Is Null)
);
 
Hij werkt in jouw voorbeeld :). Ik zou zeggen: kom eens met de volledige db :)
 
de volledige db is veel te groot, maar ik heb het vorige voorbeeld uitgebreid naar 8 velden.
de query werkt, maar ik mis 2 records in de query die beginnen met A.A=1 en B.A = 4.
Beide tabellen bevatten 6 records, er zijn 2 gelijke records, dan moeten er 8 ongelijke overblijven in de query?
kun je je licht erover laten schijnen? zou niet weten waar het aan ligt.
Gr,
André
 

Bijlagen

Ik krijg de 'fout' er zo op het eerste gezicht ook niet uit, maar ik ben ondertussen in een hele andere richting aan het denken: een functie waarbij je de 2 tabellen + het aantal te vergelijken velden in een functie inleest, en daarin de records met elkaar vergelijkt. De uitkomst van die functie zou een Boolean kunnen zijn, dus Waar of Onwaar. Gebaseerd op of alle velden in 2 te vergelijken records uit de 2 records gelijk zijn of niet. De records die niet gelijk zijn zet je in een virtuele tabel, en die hang je aan een formulier om te bekijken. Of zoiets :)
 
Nu begrijp ik het helemaal niet meer :confused: kun je me op weg helpen? :(
 
Status
Niet open voor verdere reacties.

Nieuwste berichten

Terug
Bovenaan Onderaan