2 queries naar 1 query

Status
Niet open voor verdere reacties.

maomanna

Gebruiker
Lid geworden
20 feb 2014
Berichten
234
Hallo,

Inmiddels heb ik mijn dossier db wat omgegooid.

heb ik nu een aantal testtabellen gemaakt.

[table="width: 500, class: grid, align: left"]
[tr]
[td]EisnaamID[/td][td]Eisnaam[/td]
[/tr]
[tr]
[td]1[/td][td]ID bewijs[/td]
[/tr]
[tr]
[td]2[/td][td]Diploma[/td]
[/tr]
[/table]

2. Tabel tblFunctie (Functies)
[table="width: 500, class: grid, align: left"]
[tr]
[td]iFunctieID[/td][td]Functiecode[/td][td]Functienaam[/td]
[/tr]
[tr]
[td]1[/td][td]1001[/td][td]Poetser[/td]
[/tr]
[/table]

3. Tabel tblFunctieEis (vereiste documenten per functie)
[table="width: 500, class: grid, align: left"]
[tr]
[td]iFunctieEisID[/td][td]iFunctieID[/td][td]iEisnaamID[/td][td]datumStart[/td][td]datumEind[/td]
[/tr]
[tr][td]1[/td][td]1[/td][td]1[/td][td]01-01-2015[/td][td][/td][/tr]
[tr]
[td]2[/td][td]1[/td][td]2[/td][td][/td][td][/td][/tr]

[/table]

4. Tabel Werknemer (tabel met werknemers)
[table="width: 500, class: grid, align: left"]
[tr]
[td]iWerknemerID[/td][td]persnummer[/td][td]achternaam[/td][td]iFunctieID[/td][td]indienst[/td]
[/tr]
[tr]
[td]1[/td][td]2009[/td][td]Testpersoon[/td][td]1[/td][td]01-01-2014[/td]
[/tr]
[/table]

5. Tabel tblRegistratieEis (Wat er aanwezig is in dossier)
[table="width: 500, class: grid, align: left"]
[tr]
[td]iRegistratieID[/td][td]iWerknemerID[/td][td]iEisnaamID[/td]
[/tr]
[tr]
[td]1[/td][td]1[/td][td]2[/td]
[/tr]
[/table]

Wel heb ik nu 2 simpele queries:

Code:
SELECT tblFunctieEis.iFunctieEisId, tblFunctieEis.iFunctieId, tblFunctieEis.iEisnaamId, tblFunctieEis.dStart, tblFunctieEis.dEind
FROM tblFunctieEis;

Code:
SELECT Werknemers.*, tblRegistratieEisId.iEisnaamId
FROM tblEisnaam INNER JOIN ((Werknemers INNER JOIN tblRegistratieEisId ON Werknemers.ID = tblRegistratieEisId.iWerknemerID) INNER JOIN (tblFunctieEis INNER JOIN tblFunctie ON tblFunctieEis.iFunctieId = tblFunctie.iFunctieID) ON Werknemers.iBigfunctieID = tblFunctie.iFunctieID) ON tblEisnaam.EisnaamID = tblFunctieEis.iEisnaamId;

Nu loop ik vast op het combineren van deze twee.

Wat ik nu dus nodig heb is een query die voor de werknemer de documenten ophaalt die *niet* aanwezig zijn.

de selectie vind plaats obv functies.
Wat voor join ik ook maak, er komt niet uit wat ik wil.

iemand een tip?
 
Je hebt sowieso een Outer Join nodig en een filter.
 
Die outer join moet dan komen op de plek van de inner join?

Code:
SELECT Werknemers.*, tblRegistratieEisId.iEisnaamId
FROM tblEisnaam OUTER JOIN ((Werknemers OUTER JOIN tblRegistratieEisId ON Werknemers.ID = tblRegistratieEisId.iWerknemerID) OUTER JOIN (tblFunctieEis INNER JOIN tblFunctie ON tblFunctieEis.iFunctieId = tblFunctie.iFunctieID) ON Werknemers.iBigfunctieID = tblFunctie.iFunctieID) ON tblEisnaam.EisnaamID = tblFunctieEis.iEisnaamId;

Of moet die OUTER JOIN in de nieuwe query waar hij samen gevoegd gaat worden?

Bij elke outer join die ik gebruik krijg ik een foutmelding "De component FROM bevat een syntaxfout"
 
Laatst bewerkt:
D'r klopt weinig van je voorbeeldtabellen; ik ben net een kwartier bezig geweest om ze eerst in Excel te plakken en dan met de namen die jij ze hebt gegeven (de eerste heeft zelfs geen naam, en Werknemers een verkeerde) in Access te plakken en de query te draaien. Geen resultaat, want je tabellen kloppen niet. Ik had die tijd (het importeren) natuurlijk liever gestoken in het zoeken naar de oplossing.... Graag een goed voorbeeld dus!
 
Excuses voor de tijdverspilling.

Donderdag zal ik de db uploaden zodat hij compleet is.

Er is idd nog een tabel waar de werknemer een id krijgt. Met voornaam achternaam functieid
 
Laatst bewerkt:
Maomanna,

Is dit ongeveer wat je zoekt?

Code:
SELECT 
  A.Personeelsnummer, 
  A.Voornaam, 
  A.Achternaam, 
  B.Functienaam, 
  D.Eisnaam
FROM documentnamen D, functieeisen C, functies B,  werknemers A
WHERE B.Id = A.functieID   AND  B.Id = C.iFunctieId AND D.Id = C.iEisnaamId;

Veel Succes.
 
Hij laat nu alleen zien wat aanwezig moet zijn, wat opzich al een hele vooruitgang is.

Nu moet hij alleen nog filteren wat er wel in zit en wat niet en datgene ontbreekt laten zien.

In de tabel registratieeisen staat wat er wel in zit.

Code:
SELECT A.Personeelsnummer, A.Voornaam, A.Achternaam, B.Functienaam, D.Eisnaam, E.iEisnaamId
FROM werknemers AS A, functies AS B, functieeisen AS C, documentnamen AS D, registratieeisen AS E
WHERE (((B.Id)=[A].[functieID] And (B.Id)=[C].[iFunctieId]) AND ((D.Id)=[C].[iEisnaamId]) AND ([C].iEisnaamId = E.iEisnaamId));

Als ik dit toevoeg, laat hij alles meermaals zien.
 
Laatst bewerkt:
Is ook een oplossing. Er zijn verschillende wegen die naar het juiste resultaat leiden :)
 
haha ja dat snap ik. Net als de meerdere wegen naar Rome.

Mag ik je vragen of je een aanvulling wil geven op de post van Elsendoorn2134 die meer naar het resultaat (wat wel vereist is, maar niet geregistreerd is) komt?
 
Code:
SELECT distinct 
werknemers.Personeelsnummer, werknemers.Voornaam, werknemers.functieID, RE.iEisnaamId
FROM werknemers, registratieeisen AS RE INNER JOIN qry_reis ON RE.RegistratieID = qry_reis.RegistratieID
WHERE (((Exists (select FE.iEisnaamId
From functieeisen AS FE
Where FE.iFunctieID = RE.iFunctieId AND
FE.iEisnaamId = RE.iEisnaamId))=False));

Nu krijg ik weliswaar zichtbaar wat er in hoort te zitten, maar nog niet wat er ontbreekt.
Eigenlijk hetzelfde als wat Elsendoorn aangaf.
 
Ik heb heel wat tijd naar je db gekeken, en volgens mij zit er een fout in de constructie. D.w.z.: de constructie van de tabellen is wel goed, maar de koppeling niet. In de tabel [RegistratieEisen] leg je een [WerknemerID] vast (goed) en een [EisnaamID] (fout). Je hebt een tabel FunctieEisen, en die legt de combinatie vast van functie en eis (de tabel die vreemd genoeg Documenten heet). Daarbij is het FunctieEisID uniek, en mag elke combinatie van [FunctieID] en [EisNaamID] uniek. Dus: als je het [FunctieID] hebt, weet je welke documenten daar aan vast zitten. En van de Werknemer weet je ook de FunctieID, en weet je dus welke documenten er nodig zijn (query op Functie+FunctieEisen+Documenten)) en welke documenten er binnen zijn (query op Werknemer+RegistratieEisen). Maar de gegevens in RegistratieEisen kloppen nu dus niet, want je legt de verkeerde waarden vast.
 
Dat is erg duidelijk verwoord en verklaard dan dus ook waarom het steeds niet lukte.
Het is wel zo dat ik met de huidige inrichting weet wat erin zit en wat erin hoort te zitten. (met losse queries).
Alleen gaat er iets mis met de vergelijking.
handig en moet het dus ergens los bij.

Als alles goed zit, behalve de registratietabel. Welke waarde moet ik daar dan toevoegen?

Op Tweakers, waar de vraag ook staat, kreeg ik terug:
- Schrijf een query die voor de functie van de werknemer de vereiste documenten ophaalt
- Schrijf een query die voor de werknemer de aanwezige documenten ophaalt
- Combineer deze tot een query die voor de werknemer de documenten ophaalt die *niet* aanwezig zijn.

Maar dat is dus eigenlijk veel te simpel gezegd, daar de info niet klopt.
Lastig dat vast zitten.
 
Laatst bewerkt:
Met de huidige inrichting is dit de enige manier; zo heb ik het zelf ook gedaan. Beide queries zijn simpel te maken. Als je de twee 'hoofdqueries' (Functie_Eisen + Werknemer_Registratie) hebt gemaakt, kun je een nieuwe query maken op basis van deze twee queries. Je koppelt ze aan elkaar op basis van FunctieID, want dat is de overeenkomende factor. Je maakt vervolgens een Outer Join van Functie_Eisen --> Werknemer_Registratie want je wilt alle eisen zien die bij een functie horen, en de documenten die per werknemer zijn ingevuld.
 
Dat klopt helemaal!
En dan filteren op waar het niet overeen komt.

Helaas krijg ik weer een hoop dubbele resultaten. In totaal staan er in het voorbeeld 27 geregistreerde documenten en die zouden na filtering gelijk of minder moeten zijn.

met
Code:
SELECT DISTINCT Werknemer_Registratie.iWerknemerID, Functie_Eisen.iFunctieId, Functie_Eisen.iEisnaamId, Werknemer_Registratie.iEisnaamId
FROM Functie_Eisen LEFT OUTER JOIN Werknemer_Registratie ON Functie_Eisen.iFunctieId = Werknemer_Registratie.functieID;

Krijg ik 384 resultaten, wat dus niet goed is.

Hij lijkt elke eis af te zetten tegen elk geregistreerd document.
Dus als ik voor werknemerID 1 6 geregistreerde documenten heb, pakt hij 6x eis 1, 6x de volgende etc etc.
access_dubbel.jpg
 
Van iemand kreeg ik de tip:

[Hele zooi] LEFT JOIN tblRegistratieEis re ON re.iWerknemerID=… AND re.iEisnaamID=…
WHERE re.iRegistratieEisID IS NULL

Door de LEFT JOIN neemt ie alle records links van de left join mee (ook als er niets gevonden wordt rechts van de join) en door de Where-conditie filter je op combinaties die NIET terug te vinden zijn.

Zelf heb ik echt geen idee meer en de moed begint me aardig in de schoenen te zakken.
allerlei join errors etc.
 
Laatst bewerkt:
Een INNER JOIN en een LEFT JOIN zijn niet zo heel verschillend, en je zou sowieso van de resultaten maar één record moeten hebben. Enige verschil: als in de 'linker' tabel 300 records zitten, en in de 'rechter' tabel maar 180 records gekoppeld zijn, zie je bij de Inner join 180 records (de gekoppelde) en bij de Left join 300 (ook de 120 niet-gekoppelde). Om het verhaal compleet te maken: een Right join zou in deze situatie hetzelfde opleveren als e Inner Join, omdat je nog steeds maar 180 records rechts hebt die ook in de linker tabel zitten.
Jouw resultaat riekt naar een Cartesisch product. Zonder voorbeeldje wordt en blijft het lastig :)
 
Hierbij het voorbeeld.

Bekijk bijlage samenvoegquery 2.0.zip

Het is idd een erg ingewikkeld verhaal. Zelf snap ik er weinig meer van.
Wellicht ook dat dit gewoon ook boven mijn pet gaat.

Zelf heb werkt dit naar behoren, alleen kan ik geen "vanaf-deze-datum-is-dit-document-van-toepassing" maken/invoegen.
Of is hier wel een mogelijkheid voor?

Deze opzet werkt insich best goed.
Bekijk bijlage Test voor forum.zip
 
Laatst bewerkt:
Ik snap dat je Left Join query niet het goede resuiltaat geeft, want je koppelt de verkeerde velden. Bij een Join (maakt niet uit welk type) koppel je het sleutelveld uit Tabel1 aan het gekoppelde veld uit Tabel2. Je wilt namelijk uit tabel1 de records maar één keer zien. Daarnaast bepaal je dus of je alle gegevens wilt zien uit Tabel1 (Left Join) of alleen die records die ook een record hebben in tabel2 (Inner Join). Jij koppelt dus op een veld dat niet uniek is, en daarom krijg je toch een soort van Cartesisch product.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan