[SQL] Subqueries of joins?

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

  • amoen
  • Registratie: Juni 2003
  • Laatst online: 18-11-2025
hai...

ik heb deze tabellen

client » client_2_traject » traject » rappel_2_traject

en tussen de tabellen zit een id-link maar ik moet in 1x van client naar rappel_2_traject
hiervoor gebruik ik deze nogal omslachtige querie:

code:
1
2
3
4
5
6
7
SELECT * FROM `rappel_2_traject` WHERE `traject_id` IN (
  SELECT `traject_id` FROM `traject` WHERE `traject_id` IN (
    SELECT `traject_id` FROM `client_2_traject` WHERE `client_id` IN (
      SELECT `client_id` FROM `client` WHERE `user_id`='".$_SESSION["safe_id"]."'
    )
  ) 
) ORDER BY `rappel_datum`


hehe...
zoals je ziet nogal wat subqueries... ja ik dacht, laten we alles nou in 1x doen. dat scheelt werk. HELAAS, want op de een of andere manier issie 2 seconden aan het ratelen voordat ie klaar is. en dan heb ik nog maar heeeele kleine tabellen met alleen wat test-data erin.

nu ben ik al aan het kijken naar een JOIN, maar snap dat nog niet helemaal :s
heeft het zin om een JOIN te maken? of is mijn querie gewoon niet helemaal lekker?
het resultaat is precies wat ik nodig heb, dus dat lijkt me niet.

ik vraag geen kant en klaar script hoor, maar voordat ik me ga verdiepen in een JOIN, wil ik graag weten of dit performance-wise wel helpt... of dat mijn querie anders moet

heeeeee ..... hoe is het?


  • _MaLa_
  • Registratie: Maart 2001
  • Laatst online: 18-12-2022
Hiervoor zou je een inner join kunnen gebruiken of een Left outer join. Hierin zitten wel twee grote verschillen dus kijk uit.

kwa preformance zal het niet echt wat uitmaken waarschijnlijk misschien bij grote hoeveelheden gegevens misschien leuk om te testen ;)

[ Voor 38% gewijzigd door _MaLa_ op 02-10-2006 17:27 ]


Verwijderd

Ja je moet met joins werken, vandaar dat er ook die koppeltabellen zijn in de db.
Of het sneller is met jouw query weet ik niet, zal haast wel.

Je hebt een LEFT, INNER en AUTO join dacht ik, ik gebruik altijd een LEFT join.
INNER join geeft geen resultaat terug als het koppelveld NULL is en wat AUTO join doet weet ik niet meer.

Volgens mij wil je zoiets:

SELECT * FROM `rappel_2_traject`
LEFT JOIN traject ON (traject.traject_id = rappel_2_traject.traject_id)
LEFT JOIN client_2_traject ON (client_2_traject.traject_id = traject.traject_id)
LEFT JOIN client ON (client_2_traject.client_id = client_2_traject.client_id)
WHERE client.user_id = "blaat";

Succes

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022

Reveller

Hopla!

Naast het feit dat een LEFT JOIN hier goed te gebruiken is, heb ik altijd begrepen dat MySQL icm Subqueries geen goed idee is. SQL Server bijvoorbeeld, heeft minder problemen met subqueries, maar is dan ook een volwassener database. Los daarvan, is een JOIN natuurlijk veel mooier om te gebruiken :)

Een opmerking los van je vraag: het is nooit een goed idee om direct informatie uit sessies, cookies, get of post superglobals te pakken. Controleer de inhoud van $_SESSION["safe_id"] eerst met een functie.

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


  • Knutselsmurf
  • Registratie: December 2000
  • Nu online

Knutselsmurf

LED's make things better

Verwijderd schreef op maandag 02 oktober 2006 @ 17:25:
Ja je moet met joins werken, vandaar dat er ook die koppeltabellen zijn in de db.
Of het sneller is met jouw query weet ik niet, zal haast wel.

Je hebt een LEFT, INNER en AUTO join dacht ik, ik gebruik altijd een LEFT join.
INNER join geeft geen resultaat terug als het koppelveld NULL is en wat AUTO join doet weet ik niet meer.

Volgens mij wil je zoiets:

SELECT * FROM `rappel_2_traject`
LEFT JOIN traject ON (traject.traject_id = rappel_2_traject.traject_id)
LEFT JOIN client_2_traject ON (client_2_traject.traject_id = traject.traject_id)
LEFT JOIN client ON (client_2_traject.client_id = client_2_traject.client_id)
WHERE client.user_id = "blaat";

Succes
Deze query levert veel meer gegevens per record op dan de originele. Als je die reproduceert met joins, kom je volgens mij uit op het volgende:
SQL:
1
select rappel_2_traject.* from rappel_2_traject join client_2_traject on rappel_2_traject.traject_id=client_2_traject.traject_id where client_2_traject.client_id=$ID order by rappel_Datum

Volgens mij moet je ook geen left join, maar een inner join gebruiken.

[ Voor 34% gewijzigd door Knutselsmurf op 02-10-2006 17:32 ]

- This line is intentionally left blank -


Verwijderd

Knutselsmurf schreef op maandag 02 oktober 2006 @ 17:30:
[...]

Deze query levert veel meer gegevens per record op dan de originele. Als je die reproduceert met joins, kom je volgens mij uit op het volgende:
Ach,
code:
1
2
3
4
5
SELECT [b]rappel_2_traject.*[/b] FROM `rappel_2_traject`
LEFT JOIN traject ON (traject.traject_id = rappel_2_traject.traject_id)
LEFT JOIN client_2_traject ON (client_2_traject.traject_id = traject.traject_id)
LEFT JOIN client ON (client_2_traject.client_id = client_2_traject.client_id)
WHERE client.user_id = "blaat";


Het is slechts een voorbeeld :)

Ik raad TS aan: www.sqlcourse.com en/of eigenlijk www.sqlcourse2.com aan met name: http://sqlcourse2.com/joins.html

/edit
Ik dacht dat je velden bedoelde ipv records
Kan niet echt over de records oordelen, ken de db niet ;)

[ Voor 6% gewijzigd door Verwijderd op 02-10-2006 17:38 ]


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 22-01 23:51

NMe

Quia Ego Sic Dico.

Outer joins lijken me inderdaad vrij onzinnig in deze situatie. Zo te lezen zijn er hier een paar mensen die een enkeltje Programming FAQ - SQL kunnen gebruiken. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:29
Joins gebruiken, en eventueel de nodige indexen leggen op de velden waar je op joined.

https://fgheysels.github.io/


  • dusty
  • Registratie: Mei 2000
  • Laatst online: 25-11-2025

dusty

Celebrate Life!

Buiten het feit dat je inderdaad joins moet gebruiken ( geloof dat dat al gezegd is ) moet je ook goed opletten dat je geen dubbel werk doet in welke query je ook maakt.
SELECT `traject_id` FROM `traject` WHERE `traject_id` IN (
deze select komt uit jouw eigen query, waarin je dus de traject_id teruggeeft waar de traject_id voorkomt in een bepaalde query, deze subquery had je er dus tussenuit kunnen knippen.

Als je subqueries of de join gebruikt moet je dus wel zeer goed opletten dat er indexes staan op de kolommen die je gebruikt in je combine statement, dat scheelt 'een beetje' tijd bij het selecteren namelijk.

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


  • amoen
  • Registratie: Juni 2003
  • Laatst online: 18-11-2025
halleluja

goeiemorgen wat een replies :Y)

ik moet me echt even verdiepen. dus iig een inner of left join.
maar zo te zien zijn de meningen hierover verdeeld :)

zal de verschillende opties eens proberen en terug posten wat de resultaten zijn.
superbedankt ook voor de links en de $_SESSION tips!

heeeeee ..... hoe is het?


  • amoen
  • Registratie: Juni 2003
  • Laatst online: 18-11-2025
resultaat originele querie (SUBs):
(3 totaal, Query duurde 1.5611 sec) « :'(

resultaat nieuwe querie (LEFT JOIN):
(3 totaal, Query duurde 0.0251 sec) « :*)

resultaat nieuwe querie (INNER JOIN):
(3 totaal, Query duurde 0.0046 sec) « _/-\o_


scheelt NOGAL!

dit is mijn uiteindelijke querie:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT *
FROM `rappel_2_traject`
INNER JOIN `traject` ON ( traject.traject_id = rappel_2_traject.traject_id )
INNER JOIN `client_2_traject` ON ( client_2_traject.traject_id = traject.traject_id )
INNER JOIN `client` ON ( client.client_id = client_2_traject.client_id )
WHERE (
`user_01` = '".$mijn_id."'
OR `user_02` = '".$mijn_id."'
OR `user_03` = '".$mijn_id."'
OR `user_04` = '".$mijn_id."'
)
AND `rappel_datum` <= '".$check_datum."'
AND `rappel_status` = '0'
AND `traject_actief` = '1'
ORDER BY `rappel_datum` 


heb zojuist ook nog ontdekt dat alle WHERE en AND statements helemaal achteraan moeten :), daar ging de join bij mij in eerste instantie steeds op fout.

erg bedankt dit scheelt echt enkele seconden op de gehele pagina voor mij!
heb de code van computeraap gebruikt en net als knutselsmurf verder aangepast. en ook de FAQ-links erbij genomen die ik hier voorbij zag komen!

goeie tips allemaal!!

ps: de SELECT rappel_2_traject.* is niet nodig, ik heb JUIST al die kolommen nodig. ik haalde die namelijk na mijn eerste querie weer op door extra queries... haha ik ben echt dom

[ Voor 6% gewijzigd door amoen op 03-10-2006 09:10 ]

heeeeee ..... hoe is het?


  • Pete
  • Registratie: November 2005
  • Laatst online: 31-10-2025
amoen schreef op dinsdag 03 oktober 2006 @ 09:08:
resultaat nieuwe querie (LEFT JOIN):
(3 totaal, Query duurde 0.0251 sec) « :*)

resultaat nieuwe querie (INNER JOIN):
(3 totaal, Query duurde 0.0046 sec) « _/-\o_
Heb je wel gekeken of een LEFT JOIN en een INNER JOIN allebei hetzelfde gewenste resultaat geven? (Er zal verschil tussen moeten zitten als bijv. je Traject nog geen Client bevat. Het is niet zo dat LEFT en INNER hetzelfde doen alleen de een iets sneller)

petersmit.eu


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Een A 1:n B relatie met een filter op B en een fetch van A is beter af met een subquery, tenzij A een compound PK heeft. Dit levert een snellere query op omdat je niet het risico dat je duplicates krijgt in A, die je met DISTINCT weer moet wegfilteren. DISTINCT kan niet altijd in een query gebruikt worden en je moet dan op de client filteren op duplicates.

Het is dus zeker niet altijd zaak voor joins te kiezen.

(edit) Ik zie dat je de meest TRIESTE database EVER gebruikt: MySql, tja, dan is beginnen over subqueries niet eens aan de orde.

[ Voor 13% gewijzigd door EfBe op 03-10-2006 09:26 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • amoen
  • Registratie: Juni 2003
  • Laatst online: 18-11-2025
phsmit schreef op dinsdag 03 oktober 2006 @ 09:22:
[...]
Heb je wel gekeken of een LEFT JOIN en een INNER JOIN allebei hetzelfde gewenste resultaat geven? (Er zal verschil tussen moeten zitten als bijv. je Traject nog geen Client bevat. Het is niet zo dat LEFT en INNER hetzelfde doen alleen de een iets sneller)
jazeker... er MOET altijd een relatie bestaan. maw: het gevonden traject MOET een client hebben.
EfBe schreef op dinsdag 03 oktober 2006 @ 09:24:(edit) Ik zie dat je de meest TRIESTE database EVER gebruikt: MySql, tja, dan is beginnen over subqueries niet eens aan de orde.
nou nou. als het werkelijk de meest trieste ever was... zou het onwerkbaar zijn en zouden er niet zoveel mensen gebruik van maken. een ferrari zal best beter zijn dan een fiat panda... maar als ik heel tevreden van A naar B kom in die panda, ga ik niet klagen... vooral niet omdat mijn provider alleen panda's in de aanbieding heeft

heeeeee ..... hoe is het?


Verwijderd

EfBe schreef op dinsdag 03 oktober 2006 @ 09:24:
Een A 1:n B relatie met een filter op B en een fetch van A is beter af met een subquery, tenzij A een compound PK heeft. Dit levert een snellere query op omdat je niet het risico dat je duplicates krijgt in A, die je met DISTINCT weer moet wegfilteren. DISTINCT kan niet altijd in een query gebruikt worden en je moet dan op de client filteren op duplicates.

Het is dus zeker niet altijd zaak voor joins te kiezen.

(edit) Ik zie dat je de meest TRIESTE database EVER gebruikt: MySql, tja, dan is beginnen over subqueries niet eens aan de orde.
er zijn immers zoveel wijdbeschikbare (op hosts ed) andere gratis databases beschikbaar :?

  • NetForce1
  • Registratie: November 2001
  • Laatst online: 11-02 16:00

NetForce1

(inspiratie == 0) -> true

Verwijderd schreef op dinsdag 03 oktober 2006 @ 14:58:
[...]

er zijn immers zoveel wijdbeschikbare (op hosts ed) andere gratis databases beschikbaar :?
Wat dacht je van Postgresql? Er zijn genoeg hosters die dat aanbieden hoor. Maargoed, dit is wel behoorlijk off-topic.

De wereld ligt aan je voeten. Je moet alleen diep genoeg willen bukken...
"Wie geen fouten maakt maakt meestal niets!"


  • nescafe
  • Registratie: Januari 2001
  • Nu online
amoen,

Eigenlijk schrik ik van het datamodel dat je hier gebruikt. Het voorbeeld geef je hierin zelf:
`user_01` = '".$mijn_id."' OR `user_02` = '".$mijn_id."' OR `user_03` = '".$mijn_id."' OR `user_04` = '".$mijn_id."'

Tenzij dit veld in elke tabel apart voorkomt duidt dit op een onjuist datamodel en zou je deze kolommen in een enkele kolom in een aparte tabel moeten samenvoegen met een verwijzing naar het originele record. Je kunt dan met een extra join en een enkele voorwaarde dezelfde gegevens sneller en eenduidiger terugkrijgen.

Probeer daarnaast de kolommen die je wilt gebruiken in je query te benoemen. Hiermee voorkom je nutteloze overdracht van data en kun je je datamodel aanpassen zonder dat de set met data in je code ineens groter wordt of je onverwachte foutmeldingen krijgt.

* Barca zweert ook bij fixedsys... althans bij mIRC de rest is comic sans


Verwijderd

Naast dat ik me aansluit bij voorgaande bericht:

AND `rappel_datum` <= '".$check_datum."'
AND `rappel_status` = '0'
AND `traject_actief` = '1'

Prachtige joins maar wanneer je erg veel records gaat hebben kan het beter opgelost worden:

Filter middels subquery op bovenstaande kolommen en doe dan pas een join anders join je onnodig op alle records die niet voldoen aan de bovenstaande voorwaarden.

Mocht je eens iets database achtigs gaan doen bij een andere provider of op je thuis-pc, kijk eens naar Oracle's gratis database versie. Kun je Oracle SQL Developer gaan gebruiken en kun je gemakkelijk de cost (executie-pad) van een query bekijken. Loont zeker de moeite als je in de miljoen records gaat lopen.

  • nescafe
  • Registratie: Januari 2001
  • Nu online
Waarom de query onnodig complex maken? Je RDMS zou bij de table-scan al de relevante restricties toe kunnen (moeten) passen en met het gebruik van subqueries verplicht het eigenlijk gebruik te maken van temporary tables (correct me if I'm wrong).

Ik denk dat je als de query zo vlak mogelijk houdt, de optimizer ook het best zijn werk kan doen. Uiteraard heeft wel wel zin om beide opties uit te proberen omdat situaties nu eenmaal verschillen.

* Barca zweert ook bij fixedsys... althans bij mIRC de rest is comic sans


  • gvdh81
  • Registratie: Juli 2001
  • Laatst online: 22-01 09:01

gvdh81

To got or not to got..

Even een (beetje) off-topic vraagje.. Ik vond het onzinnig om dit in een nieuw topic te plaatsen, aangezien er een simpel antwoord op is.. Het zit me namelijk al een tijdje dwars..

Simpel pseudo voorbeeldje dat iedereen moet snappen :p
SQL:
1
SELECT a.naam, b.* FROM auteur a, boek b WHERE a.auteurid=b.auteurid AND a.auteurid=3


Is dit een inner join? Zo niet, eventuele voordelen/nadelen van deze constructie t.o.v. joins?

Bah, zie net dat dit inderdaad een inner join is.. Ben nu de FAQ aan het lezen...

[ Voor 8% gewijzigd door gvdh81 op 05-10-2006 22:54 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:29
Ja, dit is een inner join....
Nadelen ? Het is gewoon een andere notatie.

https://fgheysels.github.io/


  • D4V3
  • Registratie: Augustus 2003
  • Laatst online: 19-03-2021
EfBe schreef op dinsdag 03 oktober 2006 @ 09:24:
(edit) Ik zie dat je de meest TRIESTE database EVER gebruikt: MySql, tja, dan is beginnen over subqueries niet eens aan de orde.
Argumenteer dit eens dan,
En verklaar dan is waarom spelers met megadatabases als Flickr, Google, Amazon.com, Slashdot, Yahoo, Wikipedia en CNET met MySQL werken? Weet je wanneer je triest bent? als je een goed product waar je naar alle waarschijnlijkheid geen echte ervaring mee hebt loopt af te kraken for no apparent reason...

op-voorraad.nl - Realtime voorraad updates voor de Playstation 5!


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:29
MySQL is gewoon een brakke DB waar geen enterprise kritieke app's zouden moeten op draaien. Ik weet het niet, maar het zou mij toch zo verwonderen als Amazon, Google, Yahoo etc.. hun kritische app's aan MySQL toevertrouwen.
Wat mij ergert is dat sommige MySQL - fanboys gewoon de tekortkomingen van het product neit willen inzien, maarja, misschien hebben ze nog nooit een ander DBMS van dichtbij bekeken.

https://fgheysels.github.io/


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
whoami schreef op donderdag 05 oktober 2006 @ 23:31:
MySQL is gewoon een brakke DB waar geen enterprise kritieke app's zouden moeten op draaien. Ik weet het niet, maar het zou mij toch zo verwonderen als Amazon, Google, Yahoo etc.. hun kritische app's aan MySQL toevertrouwen.
Wat mij ergert is dat sommige MySQL - fanboys gewoon de tekortkomingen van het product neit willen inzien, maarja, misschien hebben ze nog nooit een ander DBMS van dichtbij bekeken.
Helemaal mee eens. Ook ik ben niet zo'n fan van MySQL maar ik laat het gewoon in z'n waarde; een leuk DB'tje om je website-je mee te bouwen :+
MySQL zuigt helemaal niet als je het gebruikt in bepaalde omstandigheden. En MSSQL, Oracle en vele andere RDBMS-en zuigen op hun tijd ook wel eens ontzettend hard.
Wat mij stoort is dat het in dit soort dingen (windows/linux/mac, Intel/AMD, Firefox/Opera/IE discussies) altijd over en weer hakketakken is zonder er iets wezenlijks mee te bereiken... we zijn toch ondertussen wel allemaal (bijna) volwassen, of niet soms? We zijn, mag ik hopen, de zandbak ondertussen toch wel overstegen?

Dus... kunnen we nu weer ontopic? ;)

[ Voor 8% gewijzigd door RobIII op 05-10-2006 23:41 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • EfBe
  • Registratie: Januari 2000
  • Niet online
D4V3 schreef op donderdag 05 oktober 2006 @ 23:27:
[...]
Argumenteer dit eens dan,
En verklaar dan is waarom spelers met megadatabases als Flickr, Google, Amazon.com, Slashdot, Yahoo, Wikipedia en CNET met MySQL werken? Weet je wanneer je triest bent? als je een goed product waar je naar alle waarschijnlijkheid geen echte ervaring mee hebt loopt af te kraken for no apparent reason...
Als ik met query met een subquery de INFORMATION_SCHEMA views uitvraag op de allerlaatste mysql 5 release en dan de melding krijg dat mn database corrupt is (terwijl ik deze NET zelf heb aangemaakt middels een DDL SQL scriptje) en ik eventjes een of andere routine moet runnen, en wanneer ik het met een join doe deze melding niet komt, dan is het een brakke database, wat eigenlijk de naam 'database' niet mag dragen: ik wil niet van een db horen dat de database corrupt is, want het is de taak van de db engine om te zorgen dat deze niet corrupt raakt. Harddisk failures, ala, maar daar was hier geen sprake van. Ik werk met veel verschillende typen databases, maar er is er maar 1 die echt brak is: MySql.

En als jij nu gaat beweren dat ik geen ervaring met mysql heb, tja, dan moet je dat maar doen. MySql 'goed' noemen noem ik naief of onwetend. Je kunt nl. niet beter weten, en dat is prima, maar ga mij niet vertellen dat ik niet weet waar ik over praat.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com

Pagina: 1