[SQL] "dubbele records" niet in join.

Pagina: 1
Acties:
  • 146 views sinds 30-01-2008
  • Reageer

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 19:18

Robtimus

me Robtimus no like you

Topicstarter
Ik heb 2 tabellen, customer en contact_details, met in de laatste een willekeurige verzameling telefoonnummers, emailadressen etc.

customer: pkey, name, andere zut
contact_details: pkey, customer_key, type (phone, email, etc), details (het echte telefoonnummer etc).

Ik heb nu een view gemaakt voor alle benodigde contact_details, zoals telefoon en email. Nu moet ik die gaan joinen met de customer, maar wel zo dat er per customer maar 1 rij overblijft. Het moet wel mogelijk blijven om meerdere telefoonnummers of emailadressen in te geven, maar ik wil er maar 1 gebruiken voor deze join.

Laat ik me maar even richten op telefoonnummers, en die view noemen we phone.
Stel ik heb 2 customers, 1 en 2, en de volgende contact_details (pkey, cust_key, type, details):
1, 1, 0, 12345
2, 1, 0, 98765
3, 2, 0, 45678

Nu levert de standaard left outer join (ik wil ook customers zonder contact details vinden) 3 rijen op (cust pkey, details pkey, details):
1, 1, 12345
1, 2, 98765
2, 3, 45678
SQL:
1
select * from customer left outer join contact_details on customer.pkey = contact_details.customer_key

Nu wil ik deze tabellen alleen dus zodanig joinen dat ik eruit krijg (cust pkey, details pkey, details)
1, 1, 12345 (of 1, 2, 98765)
2, 3, 45678

Een van de 2 regels voor customer 1 moet dus wegvallen.

Ik heb al zitten kijken naar joinen op een beperkte selectie van contact_details, maar dan krijg ik weer te weinig data terug (bv customer 2 die opeens geen telefoonnummer heeft).

Is het mogelijk wat ik wil met maar 1 enkele query? Distinct heb ik ook al geprobeerd, maar die werkt alleen over volledige rijen (van geselecteerde kolommen).

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
GROUP BY: P&W FAQ - SQL

Oops! Google Chrome could not find www.rijks%20museum.nl


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 19:18

Robtimus

me Robtimus no like you

Topicstarter
Ik ken GROUP BY wel, maar dan moet elk veld dat ik wil tonen OF in de GROUP BY zitten, of in een aggregate functie. Zet ik het in de GROUP BY dan krijg ik exact hetzelfde gedrag, en ik zou niet weten welke aggregate functie ik zou moeten nemen voor het details veld (plus 1 ander, maar dat boeit niet zoveel).

Hmm, dat andere veld kan eventueel weg, en dan werkt MAX bv wel. Bedankt dus, ik heb een oplossing (dat ik hier zelf nog niet opgekomen ben zeg...).

Heeft iemand misschien ook een idee hoe ik het eerst ingegeven telefoonnummer kan gebruiken, mocht dat bv beter zijn? Of juist het laatste?

[ Voor 43% gewijzigd door Robtimus op 04-05-2005 15:55 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
IceManX schreef op woensdag 04 mei 2005 @ 15:51:
en ik zou niet weten welke aggregate functie ik zou moeten nemen voor het details veld (plus 1 ander, maar dat boeit niet zoveel).
De database kan het niet voor je beslissen, je moet zelf een keuze maken. Daarom is toch group by wat je nodig hebt. MAX() mischien?

Oops! Google Chrome could not find www.rijks%20museum.nl


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
In sommige rdbms en kun je zelf aggregate functions schrijven. Mischien kan je daar een soort discard() function mee maken ofzo.
Verder ben ik het met P_de_B eens dat de database niet voor je kan beslissen. Je zult ergens toch aan moeten geven welke je wel en welke je niet wilt

dus dan zou idd de max() of min() function een oplossing zijn dan krijg je altijd de hoogste of de laagste

[ Voor 17% gewijzigd door Woy op 04-05-2005 16:47 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 19:18

Robtimus

me Robtimus no like you

Topicstarter
Totdat ik erachter kom hoe het laatst toegevoegde record (meest recente is meestal ook echt in gebruik) kan gebruiken op deze manier ga ik toch voor MAX.

P, hardstikke bedankt, dat ik hier zelf niet opgekomen ben...

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Als je een datum veld hebt met de datum wanneer het record is toegevoegd dan zou je eventueel iets met een Max op dat veld en een subselect kunnen doen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 19:18

Robtimus

me Robtimus no like you

Topicstarter
Ik heb onlangs een andere oplossing gevonden:
SQL:
1
2
3
SELECT * FROM customer LEFT OUTER JOIN contact_details ON customer.pkey = contact_details.customer_key WHERE contact_details.pkey IN
(SELECT MAX(cd.pkey) FROM customer c LEFT OUTER JOIN contact_details cd ON cd.customer_key = c.pkey WHERE c.pkey = customer.pkey)
OR contact_details.pkey IS NULL
Die laatste OR is nodig omdat anders het hele left join voordeel verdwijnt.

Op deze manier wordt steeds het allerlaatste record meegenomen, en kun je meerdere velden van die tabel meenemen in je select.


(goh, precies wat rwb dus eigenlijk zei...)

[ Voor 5% gewijzigd door Robtimus op 30-05-2005 14:19 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs

Pagina: 1