[SQL] Join probleem

Pagina: 1
Acties:

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik heb een tabel Relaties, hier zitten de basis gegevens in voor een relatie.
Dan zijn er nog 3 andere tabellen: Leveranciers, Medewerkers en Klanten. Deze 3 hebben natuurlijk het bijbehoorende RelatieId erin zitten plus nog wat extra gegevens.

Nou wil ik alle basis gegevens van alleen de Leveranciers en Medewerkers plus de Id's van de leverancier of medewerker.

Ik kwam tot deze query (mbv Access), maar die mag dus niet echt:
code:
1
2
3
SELECT Medewerkers.MedewerkerId, Leveranciers.LeverancierId, Relaties.*
FROM (Relaties RIGHT JOIN Leveranciers ON Relaties.RelatieId = Leveranciers.RelatieId) 
RIGHT JOIN Medewerkers ON Relaties.RelatieId = Medewerkers.RelatieId;

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • momania
  • Registratie: Mei 2000
  • Laatst online: 22:44

momania

iPhone 30! Bam!

Wat gaat er dan precies niet goed?
Kijg je nog iets van een melding te zien of zo,
want dat is dan wel even handig om te vermelden...

en die tabelnaam:

RIGHT JOIN dbo_Leveranciers ON Relaties.RelatieId = Leveranciers.RelatieId
:?

Neem je whisky mee, is het te weinig... *zucht*


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Oja, tabelnaam aangepast, was alleen verkeerd in mijn post.

Onder Access krijg ik "JOIN not supported" terwijl hij zelf de SQL code heeft gemaakt.

Als ik de Query uitvoer op een MSSQL server dan krijg wel resultaat, maar dit totaal niet wat ik moet hebben.

Ik moet denk ik een geheel andere query proberen, maar welke?

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • momania
  • Registratie: Mei 2000
  • Laatst online: 22:44

momania

iPhone 30! Bam!

Kan je niet gewoon met een WHERE clausule in de weer:

code:
1
2
3
4
5
6
7
8
9
10
11
SELECT 
    Medewerkers.MedewerkerId, 
    Leveranciers.LeverancierId, 
    Relaties.*
FROM 
    Relaties,
    Leveranciers,
    Medewerkers
WHERE
    Relaties.RelatieId = Medewerkers.RelatieId AND
    Relaties.RelatieId = Leveranciers.RelatieId;


Nu mis je alleen wel de records van relaties waar dus geen medewerker
of leverancier aanhangt die je wel met een JOIN zou krijgen
De AND kan je eventueel ook nog vervangen door een OR,
probeer hier maar eens wat mee te spelen...

Neem je whisky mee, is het te weinig... *zucht*


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:04


Inderdaad... Ik snap niet waarom mensen die (imho) moeilijke syntax (right join/left join etc..) altijd maar willen toepassen.
Ik vind die manier die momania postte veel duidelijker en ik pas die ook altijd toe.

https://fgheysels.github.io/


  • momania
  • Registratie: Mei 2000
  • Laatst online: 22:44

momania

iPhone 30! Bam!

whoami schreef op 07 september 2002 @ 17:45:

[...]

Inderdaad... Ik snap niet waarom mensen die (imho) moeilijke syntax (right join/left join etc..) altijd maar willen toepassen.
Ik pas em zelf ook heel veel toe hoor.
Het heeft iig veel voordelen in relationele databases.
Als je in dit voorbeeld bv alle relaties wilt hebben, dus
ook die zonder medewerker doe je dit met een JOIN.
Met een where krijg je alleen de relaties die een medewerker
gekoppeld hebben.

't Is natuurlijk ook maar net welke informatie je precies moet hebben,
maar ik vind de JOIN's vaak wel prettig :)

Neem je whisky mee, is het te weinig... *zucht*


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:04
[nohtml]
momania schreef op 07 september 2002 @ 17:51:
[...]


Ik pas em zelf ook heel veel toe hoor.
Het heeft iig veel voordelen in relationele databases.
Als je in dit voorbeeld bv alle relaties wilt hebben, dus
ook die zonder medewerker doe je dit met een JOIN.
Met een where krijg je alleen de relaties die een medewerker
gekoppeld hebben.
Een join? Een join is gewoon een koppeling leggen tussen 2 tabellen.
De link leggen tsn 2 tabellen in de WHERE clause is ook een join.
Waar jij het op hebt, is een OUTER join. ;)
En ook dat kun je (afhankelijk van het DBMS) met een redelijk eenvoudige syntax doen.

In Informix bv:
code:
1
2
3
SELECT * 
FROM tabel1, OUTER tabel2
WHERE tabel1.id = tabel2.refid


In Oracle doe je het als volgt:
code:
1
2
3
SELECT *
FROM tabel1, tabel2
WHERE tabel1.id = tabel2.refid (+)

https://fgheysels.github.io/


  • dvdhoek
  • Registratie: Februari 2002
  • Laatst online: 30-08 22:07
De constructie met een WHERE zijn gewone INNER JOINS. De OUTER JOINS heb je met name nodig als je foreign keys geen verplichte velden zijn. Zie voor een discussie hierover [rml][ SQL] Foreign key[/rml]

  • momania
  • Registratie: Mei 2000
  • Laatst online: 22:44

momania

iPhone 30! Bam!

whoami schreef op 07 september 2002 @ 17:54:
[nohtml]
[...]

Een join? Een join is gewoon een koppeling leggen tussen 2 tabellen.
De link leggen tsn 2 tabellen in de WHERE clause is ook een join.
Waar jij het op hebt, is een OUTER join. ;)
Ohjah... ff vergeten :Z |:(
Heb al een maand geen queries meer geschreven, dus vandaar,
was ff in de warriewarrie :)

Neem je whisky mee, is het te weinig... *zucht*


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik heb natuurlijk even de hierboven genoemde query toegepast, maar deze geeft dus niet het gewenste resultaat. Ook ik heb het eerst met een WHERE geprobeerd.

De query hierboven met een AND geeft geen resultaten, met een OR geeft ie teveel resultaten (doordat een relatie of een medewerker of een leverancier kan zijn) en hij is traag (daardoor?).

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik wil dus eigenlijk alle relaties hebben die of leverancier of medewerker zijn. Ik moet natuurlijk de basis gegevens hebben. Is de relatie een leverancier dan het LeverancierId in de results en MedewerkerId null. Anders om hetzelfde.

Of is dit gewoon niet mogelijk?

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • momania
  • Registratie: Mei 2000
  • Laatst online: 22:44

momania

iPhone 30! Bam!

Wat je kan doen is in de relaties tabel een indicatie inbouwen
die verteld of het een medewerker of een leverancier is,
'M' voor medewerker en 'L' voor leverancier bijvoorbeeld,
en dan de volgende query gebruiken:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SELECT 
    Relaties.*,
    CASE (
        WHEN
            Relaties.indicatie = 'M'
        THEN
            Medewerkers.MedewerkerId
        ELSE
            Leveranciers.LeverancierId
        END
    ) AS INDICATIE_ID
FROM 
    Relaties,
    Leveranciers,
    Medewerkers
WHERE
    Relaties.RelatieId = Medewerkers.RelatieId OR
    Relaties.RelatieId = Leveranciers.RelatieId;


Dan kan met uit je restultset bepalen of je een medewerker of
een leverancier te pakken hebt en met het INDICATIE_ID uit de
juiste tabel de juiste verdere info halen...

Neem je whisky mee, is het te weinig... *zucht*


  • Delphi32
  • Registratie: Juli 2001
  • Laatst online: 31-08 21:58

Delphi32

Heading for the gates of Eden

Je kan ook met een UNION aan de slag:
code:
1
2
3
4
5
6
7
SELECT Relaties.*, 'Dit is een medewerker' AS RelatieType, Medewerkers.MedewerkerID 
FROM Relaties
INNER JOIN Medewerkers ON Relaties.RelatieID = Medewerkers.RelatieID
UNION
SELECT Relaties.*, 'Dit is een leverancier' AS RelatieType, Leveranciers.LeveranciersID 
FROM Relaties
INNER JOIN Leveranciers ON Relaties.RelatieID = Leveranciers.RelatieID

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Die werkt zeer goed, alleen een probleempje. Als ik gebruik maar van Relaties.* krijg ik deze fout:
Server: Msg 8163, Level 16, State 4, Line 1
The text, ntext, or image data type cannot be selected as DISTINCT.
Het probleem zit hem in een column van het type text, namelijk opmerking, die ik dus eigenlijk wel nodig heb.

Dan zal ik die apart moet query-en ofzo.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • dvdhoek
  • Registratie: Februari 2002
  • Laatst online: 30-08 22:07
Delphi schreef op 08 september 2002 @ 01:07:
Die werkt zeer goed, alleen een probleempje. Als ik gebruik maar van Relaties.* krijg ik deze fout:

[...]


Het probleem zit hem in een column van het type text, namelijk opmerking, die ik dus eigenlijk wel nodig heb.

Dan zal ik die apart moet query-en ofzo.
Een UNION is een impliciete DISTINCT. Als de subqueries geen overlappende records hebben, is deze distinct overbodig. Ik weet niet of ACCESS het ondersteunt, maar probeer eens een UNION ALL in plaats van UNION.

  • robjanssen
  • Registratie: September 2001
  • Laatst online: 02-08 16:10

robjanssen

Software Developer

Of als je toch DISTINCT wilt gebruiken kun je voor het Opmerking-veld CAST of CONVERT gebruiken.

CAST(Opmerking AS VARCHAR(500))
CONVERT(VARCHAR(500), Opmerking)

Succes

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
UNION ALL werkt perfect, thanks mensen! :)

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Pfff, wat ziet dit er allemaal ingewikkeld uit.
LEFT OUTER JOIN is in dit geval verschrikkelijk handig.

Wat denken jullie van onderstaande oplossing:

code:
1
2
3
4
5
SELECT R.*
FROM Relaties AS R
LEFT OUTER JOIN Medewerkers AS M ON M.RelatieID = R.RelatieID
LEFT OUTER JOIN Leveranciers AS L ON L.RelatieID = R.RelatieID
WHERE (M.MedewerkersID IS NOT NULL OR L.LeveranciersID IS NOT NULL)

De WHERE is om ervoor te zorgen dat er alleen Medewerkers of Leveranciers geselecteerd worden.

RIGHT JOIN's zijn trouwens vreselijk lelijke dingen en kunnen ook altijd vervangen worden door LEFT JOIN's.
De optimizer van MSSQL schijnt zelfs alle RIGHT JOIN's om te bouwen naar LEFT JOIN's.

Never underestimate the power of

Pagina: 1