Weet iemand een oplossing voor onderstaande kwestie?
Access 2007. Ik maak een nieuwe database met twee tabllen:
[Users]
ID – AutoNumber
username – text
desktop1 – lookup (numeric: gekoppeld aan Desktops.serial)
desktop2 – lookup (numeric: gekoppeld aan Desktops.serial)
[Desktops]
ID – AutoNumber
serial – text (serienummer van de desktop)
Deze weergave is uiteraard sterk vereenvoudigd. In dit voorbeeld heb ik een database met gebruikers en desktops. De desktops hebben allerlei eigenschappen maar ik noem hier alleen het serienummer. Je begrijpt dat omwille van normalisatie Desktops een aparte tabel moet zijn.
Ik weet niet zeker wat de juiste methode is om de desktops aan de users te koppelen. Sommige gebruikers hebben één desktop; andere twee. In het echt gaat het zelfs om drie desktops. Een juiste manier is om een koppeltabel te gebruiken maar dat is hier niet handig omdat ik dan een hele berg andere dingen moet veranderen en daar is geen tijd voor. Alternatief kan je een multidimensionele tabel maken – een array van desktops ipv één desktop-id per veld in [Users]. Dat doe ik liever niet omwille van de portability van de database.
Ik ben dus gebonden aan dit database-ontwerp.
Wat ik zoek is een manier om door de tabel met users te loopen en het id, de username en van alle desktops van de user het id + het serienummer weer te geven.
Ik gebruik de report-wizard om een report te maken van de tabel Users. De automatische inhoud daarvan negeer ik voor nu en ik maak een nieuw tekstveld. In het label schrijf ik ‘Desktop 1’ en het tekstveld zelf koppel ik aan de source users.desktop1. Dit geeft me het id van de desktop van de user in het geselecteerde record. Wat ik *wil* is het id + het serienummer.
Ik voeg daarom aan de eigenschappen van het report alle tabellen met alle velden toe, zodat ik ook toegang tot de serienummers heb.
Zodra ik dat echter doe, geeft het report geen data meer weer.
Mijn vraag is dus: hoe krijg ik het serienummer achter het id?
Of, als je het wat formeler wil hebben: hoe kan ik in een report met bound values putten uit een tabel waaraan meer dan eens wordt gerefereerd?
De query zelf ontgaat me ook een beetje. Ik ben bekend met inner en outer joins en aliases maar hoe geef ik aan dat ik twee joins naar dezelfde tabel wil maken? Dit is een minder urgent probleem maar minstens even interessant.
De laatste vraag:
select *
from eersteTabel
join deJointabel jt1 on jt1.bla1 = eersteTabel.bla2
join deJointabel jt2 on jt2.bla3 = eersteTabel.bla4
Hierbij mag bla1 == bla3, en bla2 == bla4, alleen niet allebei tegelijk.
Dankjewel voor je antwoord! Zou je de variabelen in je antwoord willen vervangen door de waarden uit mijn vraag? Dus waar moet ik precies Users gebruiken en waar Desktops.serial bijvoorbeeld? Ik begrijp wel ongeveer wat je bedoelt maar volgens mij gooi ik het een beetje door elkaar.
Sorry, ik was ondertussen weer aan het werk. Blij dat je eruit gekomen bent!
Het is helemaal goedgekomen. Dankjewel, Anna :)
select *
from users
left outer join desktops d1
on users.desktop1 = d1.ID
left outer join desktops d2
on users.desktop2 = d2.ID
#BemoeiQuery
:D
Ok, nu komen we ergens. Access lust maar één join en dit is de workaround:
select *
FROM
(
(
Users left outer join desktops d1 on users.desktop1 = d1.ID
)
left outer join desktops d2 on users.desktop2 = d2.ID
)
Eens kijken of ik het hiermee aan de praat krijg :)
Waarom niet andersom? In de table desktop aangeven welke userid erbij hoort?
Omdat er aan de tabel met users nog veel meer items gekoppeld zijn, zoals telefoons, monitors, enz.
Eigenlijk hadden we hier koppeltabellen moeten gebruiken maar zoals het nu is, is de database zelf nog redelijk voor mensen leesbaar.
Ah, en ik moet de data source van het report instellen op de query ipv op de tabellen.
Voortbordurend op jouw work-around-query…
select *
FROM
(
(
Users left outer join desktops d1 on users.desktop1 = d1.ID
)
left outer join desktops d2 on users.desktop2 = d2.ID
)
left outer join Brands D1_Brand on d1.brand_ID = D1_Brand.ID
left outer join Models D1_Model on d1.model_ID = D1_Model.ID
left outer join Brands D2_Brand on d2.brand_ID = D2_Brand.ID
left outer join Models D2_Model on d2.model_ID = D2_Model.ID
Maar ik weet niet of dat in Access kan omdat je daarnet ook problemen had met meerdere joins op dezelfde tabel.
Alternatief is om eerst een query te definieren waarin je Brands & Models linkt aan Desktops en dan die query te gebruiken in de query waar je Users en Desktops joins:
Query1:
Select *
from Desktops
left outer join Brand on Desktops.brand_ID = Brand.ID
left outer join Model on Desktops.model_ID = Model.ID
Query2:
select *
FROM
(
(
Users left outer join Query1 d1 on users.desktop1 = d1.ID
)
left outer join Query1 d2 on users.desktop2 = d2.ID
)
Maar of/hoe dat precies werkt in Access weet ik niet. Weet aardig wat van SQL, verdomd weinig (gelukkig) van Access.
We komen er wel.
Dit is hoe ik het nu werkend heb in Access:
SELECT tblUsers.FirstName & ” ” & tblUsers.LastName AS FullName, d1.id & ” – ” & d1_brand.brand & ” ” & d1_model.model & ” [” & d1.[serial number] & “]” AS FullDesktop1, d2.id & ” – ” & d2_brand.brand & ” ” & d2_model.model & ” [” & d2.[serial number] & “]” AS FullDesktop2, d3.id & ” – ” & d3_brand.brand & ” ” & d3_model.model & ” [” & d3.[serial number] & “]” AS FullDesktop3
FROM
(
(
(
(
(
(
(
(
tblUsers LEFT JOIN tblDesktops AS d1 ON tblUsers.desktop1 = d1.ID
)
LEFT JOIN tblDesktops AS d2 ON tblUsers.desktop2 = d2.ID
)
LEFT JOIN tblDesktops AS d3 ON tblUsers.desktop3 = d3.id
)
left join tblBrands d1_brand on d1.brand = d1_brand.id
)
left join tblBrands d2_brand on d2.brand = d2_brand.id
)
left join tblBrands d3_brand on d3.brand = d3_brand.id
)
left join tblModels d1_model on d1.model = d1_model.id
)
left join tblModels d2_model on d2.model = d2_model.id
)
left join tblModels d3_model on d3.model = d3_model.id
;
Nu de rest van de tabel nog :P
Dankjewel!
k Vind al die haakjes er maar mallotig uitzien. #mening #hashtag
Ben ik met je eens. Geen idee ook waarom Access het per se zo wil. Ook jammer dat je er geen “where”-join mee kan combineren. Nu moet ik alles in een outer left join doen.