[databases] relationeel vraagstukje

Pagina: 1
Acties:

  • GiLuX
  • Registratie: Juni 1999
  • Laatst online: 12-11-2025
Ik zit lekker met mysql te spelen en probeer wat relationele stuf uit maar loop meteen al vast.

stel,
ik wil uit DB de volgende lijst genereren:
code:
1
2
3
4
5
6
7
8
9
10
11
naam:
    piet

tel nrs:
    0666666
    010-1111111
    06-0888888

honden:
    bello
    fifi

dit is de database:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
table user
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | piet |  35 |
|  2 | hans |  33 |
+----+------+-----+


table phone
+----+---------+--------------+
| id | user_id | number  |
+----+---------+--------------+
|  1 |   1 | 0666666    |
|  2 |   2 | 020 22222222 |
|  3 |   1 | 010-1111111  |
|  4 |   1 | 06-0888888   |
+----+---------+--------------+

table dog
+----+---------+-------+
| id | user_id | name  |
+----+---------+-------+
|  1 |   1 | bello |
|  2 |   1 | fifi  |
+----+---------+-------+

ik doe deze left join query:
code:
1
2
3
4
5
6
7
8
9
10
11
12
SELECT 
user.id AS user_id,
user.name AS user_name,
user.age,
phone.id AS phone_id,
phone.number, 
dog.id AS dog_id,
dog.name AS dog_name 
FROM phone 
LEFT JOIN user on phone.user_id=user.id 
LEFT JOIN dog on dog.user_id=phone.user_id 
where user.id='1'

dit geeft als result:
code:
1
2
3
4
5
6
7
8
9
10
+---------+-----------+------+----------+-------------+--------+----------+
| user_id | user_name | age  | phone_id | number    | dog_id | dog_name |
+---------+-----------+------+----------+-------------+--------+----------+
|    1 | piet   |   35 |      1 | 0666666     | 1 | bello    |
|    1 | piet   |   35 |      1 | 0666666     | 2 | fifi     |
|    1 | piet   |   35 |      3 | 010-1111111 | 1 | bello    |
|    1 | piet   |   35 |      3 | 010-1111111 | 2 | fifi     |
|    1 | piet   |   35 |      4 | 06-0888888  | 1 | bello    |
|    1 | piet   |   35 |      4 | 06-0888888  | 2 | fifi     |
+---------+-----------+------+----------+-------------+--------+----------+

allemaal leuk en aardig,
maar hier kan je natuurlijk niet zoveel mee vanwege de dubbele waarden.

relationeel klopt dit dus waarschijnlijk dus niet zo,
maw, je kan hier weinig mee.

als je de data dan wel nuttig er uit wil halen, is het dan dus verstandiger om het in 2 queries te doen?

of hoe zit dat volgens de leer?

"I disagree with what you are saying, but I will defend to the death your right to say it." -- not clear who


  • WimB
  • Registratie: Juli 2001
  • Laatst online: 30-03-2024
De uitvoer van een SQL-statement is nu eenmaal een tabel. En jij wil een lijst krijgen. Jij zal dus moeten gaan programmeren, vrees ik.

  • drZymo
  • Registratie: Augustus 2000
  • Laatst online: 09-08 22:22
kleine tip: DISTINCT, mooie uitvinding ;)

(00ps was wat anders in mysql, was niet unique maar distinct dus :O)

"There are three stages in scientific discovery: first, people deny that it is true; then they deny that it is important; finally they credit the wrong person."


  • Phydomir
  • Registratie: September 2000
  • Laatst online: 17:49

Phydomir

Dennis

Je moet volgens mij nog aangeven dat bepaalde dingen gelijk zijn, dus dat user_id in table honden gelijk is aan user_id in table phone.

dus zoiets al:
code:
1
where phone.user_id = honden.user_id

dan haalt ie dubbele dingen geloof ik weg.

iRacing | Sim Gear: SimXperience AccuForce, Heusinkveld Pro, Custom 80/20 rig, Sparco R100 Sky


  • V i P
  • Registratie: December 2000
  • Laatst online: 03-08 22:49
Op donderdag 11 juli 2002 22:31 schreef Phydomir het volgende:
Je moet volgens mij nog aangeven dat bepaalde dingen gelijk zijn, dus dat user_id in table honden gelijk is aan user_id in table phone.
[...]
Dat doet ie al met de left join:
code:
1
2
LEFT JOIN user on phone.user_id=user.id 
LEFT JOIN dog on dog.user_id=phone.user_id

Verwijderd

Een wilde gok:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT 
user.id AS user_id,
user.name AS user_name,
user.age,
phone.id AS phone_id,
phone.number, 
dog.id AS dog_id,
dog.name AS dog_name 
FROM phone 
LEFT JOIN user on phone.user_id=user.id 
LEFT JOIN dog on dog.user_id=user.user_id 
WHERE phone.user_id = user.user_id
where user.id='1'

  • whoami
  • Registratie: December 2000
  • Laatst online: 20:22
Je krijgt in die vorm gewoon je gegevens terug en dat is handig.
Het is aan jou om die gegevens te gaan gebruiken/tonen etc...

https://fgheysels.github.io/


  • brammetje
  • Registratie: Oktober 2000
  • Laatst online: 12-01-2025
Op donderdag 11 juli 2002 22:28 schreef drZymo het volgende:
kleine tip: DISTINCT, mooie uitvinding ;)
mwoh, der staat geen enkele dubbele row in, hij moet al die rows hebben. waarom distinct?


Als je het volgende scriptje uitbouwt ben je al een heel eind..:
PHP:
1
<?$lastPersonId = 0;while ( $r = mysql_fetch_array( $result, MYSQL_ASSOC ) ){  if ( $r[ 'user_id' ] != $lastPersonId ){    echo 'Naam: ' . $r[ 'user_name' ];    $lastPersonId = $r[ 'user_id' ];    echo 'Telefoonnummers:';  }  echo "\t" . $r[ 'number' ];}?>

  • drZymo
  • Registratie: Augustus 2000
  • Laatst online: 09-08 22:22
Op donderdag 11 juli 2002 22:52 schreef brammetje het volgende:

[..]

mwoh, der staat geen enkele dubbele row in, hij moet al die rows hebben. waarom distinct?


Als je het volgende scriptje uitbouwt ben je al een heel eind..:
[..]
Je hebt inderdaad gelijk. Ik blaat teveel |:(

Wat wil je na 12 uur werken :z

"There are three stages in scientific discovery: first, people deny that it is true; then they deny that it is important; finally they credit the wrong person."


  • Delphi32
  • Registratie: Juli 2001
  • Laatst online: 23:25

Delphi32

Heading for the gates of Eden

Je zou alles in een grote tabel kunnen krijgen, zonder dubbele gegevens, als MySQL een UNION ondersteunt. En volgens mij doet ie dat niet, toch? (werk zelf nooit met MySQL)

* Delphi32 is van harte bereid uit te leggen hoe je dit met een union aan de praat krijgt, als dat nodig is :)

  • Paul
  • Registratie: September 2000
  • Laatst online: 02-09 10:37
Je query werkt perfect, de uitkomst is precies wat je vraagt :) Relationeel zit het dus ook helemaal goed.

Je enige probleem is nu dat je eigenlijk 2 lijstjes wilt, nl, eentje met alle honden van Piet (of eigenlijk user 1), en eentje met alle telefoonnummers.
Daar je dit in 1 query stopt is het niet zo gek dat hij alle mogelijke combinaties geeft. Dat is nl. precies wat een join doet, die plakt aan ieder record van tabel 1, alle records van tabel 2.

Wat je dus eigenlijk moet doen is 2 queries maken:
code:
1
2
3
4
5
SELECT * FROM user, phone WHERE user.id = 1

en

SELECT * FROM user, dog WHERE user.id = 1

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Delphi32: [UNION] En volgens mij doet ie dat niet, toch? (werk zelf nooit met MySQL)
Zoals zoveel, sinds 4.0.0 wel.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

De relaties in het datamodel zijn goed zoals ze zijn. Hoe je deze gegevens eruit krijgt is een andere zaak. Om dat goed te krijgen kun je een paar oplossingen kiezen.

1) Je kan jouw query gebruiken en door alle resultaten heen loopen, waarbij je dubbele voorkomen negeert.

Dit kan echter nogal uit de hand lopen als je veel tabellen gaat joinen aan 1 centrale tabel, en zeker als al die tabellen dan ook nog eens veel gerelateerde records per record van de centrale tabel hebben. Je krijgt dan namelijk een steeds groter aantal rows terug, waardoor de overhead van het oversturen van al die gegevens groot wordt.

2) Je gaat per tabel een query maken, waarin je alleen het ID van de centrale tabel meegeeft, zodat je niet eens hoeft te joinen.

Nadeel hiervan is dat je per query een bepaalde overhead hebt om die op te starten, maar de queries op zich zijn licht.

3) Dit is eigenlijk een variand op 2, maar in dit geval plak je alle queries van 2 met een UNION statement aan elkaar, waardoor je feitelijk maar 1 resultset terugkrijgt, dus daar niet al te veel overhead mee krijgt.

Aan de andere kant wordt het resultaat nogal chaotisch, omdat je kolommen in je resultaat oneigenlijk gaat gebruiken, d.w.z. dat je een kolom meerdere betekenissen gaat geven binnen de resultset, waardoor je daar weer in je code bewust van moet zijn. DIt wordt nog problematischer als het aantal kolommen in je resultset groot wordt, zeker als er later wijzigingen in de tabellen plaatsvinden, zoals extra kolommen.

Eerlijk gezeld vind ik optie 2 het netst, maar optie 1 zal in erg simpele gevallen ook voldoende zijn.

Succes :)

  • GiLuX
  • Registratie: Juni 1999
  • Laatst online: 12-11-2025
whoa,
opeens veel replies, goed!
Op donderdag 11 juli 2002 23:16 schreef drZymo het volgende:

[..]

Je hebt inderdaad gelijk. Ik blaat teveel |:(

Wat wil je na 12 uur werken :z
hehe,
die heb ik er ook net opzitten ;)
Op donderdag 11 juli 2002 23:38 schreef MrX het volgende:
....
Succes :)
tnx voor de uitleg,

alleen,
(beetje offtopic)ik had het in eerste instantie met cross joins gedaan maar dat resulteerd in een empty set als er in een tabel nog geen rows bestaan en dat los je dus wel op met left joins.

verder,
ik had gehoopt dat er toch een manier was om de data er mooier dan dit uit te laten komen met een query en wat jij nu eigenlijk voorsteld is weer een beetje terug naar af,
met een boel kleinere queries wat in princiepe meer overhead opleverd, is het niet?
Op donderdag 11 juli 2002 23:17 schreef Delphi32 het volgende:
Je zou alles in een grote tabel kunnen krijgen, zonder dubbele gegevens, als MySQL een UNION ondersteunt. En volgens mij doet ie dat niet, toch? (werk zelf nooit met MySQL)

* Delphi32 is van harte bereid uit te leggen hoe je dit met een union aan de praat krijgt, als dat nodig is :)
wie had het over MySQL? :)
klopte trouwens wel ;)

ik zal die union's eens aan een grondig onderzoek onderwerpen,
ik zal je zeker lastig vallen als ik er niet uitkom.

verder nog een vraagje,
is het handiger om wat voor reden dan ook om het veld "id" van user als "user_id" te hernoemen omdat je dan die join veel simpeler zou kunnen schrijven met "having user_id" en niet al die losse left joins?

of is dat niet relationeel verandwoord, omdat je eigenlijk een beetje verplicht bent je id's (PK's) allemaal het zelfde te noemen?

"I disagree with what you are saying, but I will defend to the death your right to say it." -- not clear who


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:34
De meest nette optie lijkt mij die, waarbij je voor het opvragen van gebruikers, honden en telefoonnummers aparte queries gebruikt. Daar zijn verschillende argumenten voor te noemen.

Ten eerste heb je op een juiste manier verschillende gegevens opgedeeld in verschillende tabellen, waarbij gegevens die 'bij elkaar horen' bij elkaar in de tabel zitten. Dit is een basisbeginsel van het ontwerpen van databases: je wilt in principe alle gegevens op precies één plek opslaan. Het is niet meer dan logisch, dat je hetzelfde principe toepast bij het raadplegen van je gegevens. Je doet een query voor alles wat je wil weten. Je wil eerst alle honden van een persoon weten en daarna alle telefoonnummers van die persoon. Honden en telefoonnummers hebben niets met elkaar gemeen (behalve dat ze toevallig dezelfde eigenaar kunnen hebben) dus is het niet logisch om ze samen in een resultset op te nemen.

Ten tweede is het doen van afzonderlijke queries efficienter. Je doet misschien juist een enkele query omdat je denkt dat dat beter is, maar de query die je nu doet, is veel complexer dan de complexiteit van de (zeer eenvoudige) afzonderlijke queries bij elkaar. Zoals al blijkt uit je voorbeeld, zal het vaak voorkomen dat gegevens vele malen voorkomen in je result set. Het genereren van die gegevens en het versturen naar de applicatie is relatief duur.

Ten derde moet nu de applicatie de resulterende gegevens weer ontrafelen en in zinnige vorm presenteren. Het idee achter het gebruik van een databaseserver met een vierde generatie taal als SQL is juist, dat je al het werk dat met het structureren van je gegevens te maken heeft, aan je database overlaat. In een nette implementatie doet je applicatie niets wat de databaseserver voor je had kunnen doen. Het gebeurt in de praktijk vrij vaak dat tegen deze regel gezondigd wordt; vaak uit efficientieoverwegingen en misschien nogwel vaker vanwege onwetenheid of onzorgvuldig ontworpen databases. Geen van allen is echt een goed excuus.

In het voorbeeld wat jij geeft, zijn het aantal afzonderlijke queries constant (een query voor de naam van de persoon, een voor zijn honden en een voor zijn telefoonnummers). Het is vaak aantrekkelijk om gegevens 'in bulk' op te vragen, als het aantal afzonderlijke queries hoog op zou kunnen lopen. Hier is dat echter niet het geval; het aantal queries wordt beperkt door het aantal tabellen dat je hebt en niet door de inhoud van die tabellen. Als je honderd personen, duizend telefoonnummers en een miljoen honden in je database hebt, heb je nog steeds maar drie queries nodig om alle gewenste gegevens te verkrijgen.

Tenslotte is er nog het voordeel dat afzonderlijke queries veel korter en minder complex zijn, waardoor je applicatie beter te doorgronden wordt. Hierdoor is de applicatie automatisch beter te onderhouden, wat een niet te onderschatten voordeel is.

Naar mijn interpretatie van 'de leer' is de optie met afzonderlijke queries dus veel beter dan het combineren van resultaten in een enkele resultset. Ik moet echter toegeven dat ik mijn ideeën over databaseontwerp voornamelijk gebaseerd heb op ervaring met het ontwerpen van (relatief simpele) databases en het structureren van data in het algemeen, dus kritiek is welkom.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:34
Op vrijdag 12 juli 2002 00:38 schreef GiLuX het volgende:
is het handiger om wat voor reden dan ook om het veld "id" van user als "user_id" te hernoemen omdat je dan die join veel simpeler zou kunnen schrijven met "having user_id" en niet al die losse left joins?

of is dat niet relationeel verandwoord, omdat je eigenlijk een beetje verplicht bent je id's (PK's) allemaal het zelfde te noemen?
Dat zou inderdaad handig kunnen zijn (al doe ik het zelf nooit). Het gaat er maar om dat je dit soort dingen consistent toepast. Als je de id key van elke tabel consequent tabelnaam_id noemt, zal er binnen je ontwerp nooit enige twijfel over de correcte naam van die id key bestaan.

Het is dan natuurlijk uit den boze om (bijvoorbeeld) een tabel 'gebuiker' te noemen en de id key 'user_id' omdat dan de relatie tussen de naam van de tabel en de id key van die tabel verbroken is.

Verwijderd

De UNION versie zou zoiets worden:
code:
1
2
3
4
5
6
7
8
9
10
11
SELECT 'user', name as blah
FROM user
WHERE id = 1
 UNION
SELECT 'phone' , number as blah
FROM phone
WHERE user_id = 1
 UNION
SELECT 'dog', name as blah
FROM dog
WHERE user_id = 1

Om te markeren waar input van 1 tabel eindigd en de volgende begint moet je een extra kolom in je resultset maken met statische waarden voor iedere tabel die je queried. Dit zorgt voor extra overhead.

Lastiger wordt het als je meerdere kolommen per tabel wil opnemen, die ook nogeens van verschillende types zijn.
ik had gehoopt dat er toch een manier was om de data er mooier dan dit uit te laten komen met een query en wat jij nu eigenlijk voorsteld is weer een beetje terug naar af,
met een boel kleinere queries wat in princiepe meer overhead opleverd, is het niet?
Hoezo terug naar af? Je gebruikt de relaties wel degelijk, alleen je joint niet.

Verder moet je bedenken dat de losse queries heel simpel zijn (zie bovenstaand voorbeeld maar dan zonder de UNIONs), waardoor ze heel snel lopen, terwijl een query met 2 JOINs en complexer is.

Ook heb je al de connectie naar de database open, dus dat is geen extra overhead, dus de algemene overhead valt heel erg mee.
verder nog een vraagje,
is het handiger om wat voor reden dan ook om het veld "id" van user als "user_id" te hernoemen omdat je dan die join veel simpeler zou kunnen schrijven met "having user_id" en niet al die losse left joins?

of is dat niet relationeel verandwoord, omdat je eigenlijk een beetje verplicht bent je id's (PK's) allemaal het zelfde te noemen?
Niets moet, alles mag. ;)

Als er in een query meer dan 1 tabel wordt gebruikt zal je de notatie [tabelnaam].[kolomnaam] gebruiken, waardoor het altijd duidelijk zal zijn welk veld je bedoelt, ook al gebruik je een kolomnaam zoals 'ID' ook elders. Ik zie dus niets tegen het gebruik van die naam.

Als je een Foreign Key opneemt in een tabel is het aan te raden inderdaad heel duidelijk te maken dat het een ID is, plus naar welke tabel het verwijst, dus UserID is bijvoorbeeld een duidelijke naam.

Enjoy :)

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op vrijdag 12 juli 2002 00:58 schreef Soultaker het volgende:
Ten tweede is het doen van afzonderlijke queries efficienter.
Sterker nog, soms is het zelfs zo dat een query met gegevens die wel (min of meer) bij elkaar horen de boel nog sneller met losse queries.

Daar liep ik tegenaan bij het maken van mijn enquete-tool hierzo :)

De resultaat pagina bouw ik op met een query _per_ vraag (dus een simpele leftjoin met een count en een group by), eenzelfde query zou ik kunnen maken voor de hele enquete (dus alle vragen +antwoorden op laten tellen en dan per vraag aparte stukken tabel genereren), dit laatste was echter een stuk trager (scheelde een factor 2 oid... zowel op postgres als in mysql en firebird/interbase) dan de losse queries :)
offtopic:
[quote]
Op vrijdag 12 juli 2002 01:05 schreef MrX het volgende:
Succes :)
[/quote]

Jij ging naar bed :+

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:34
Op vrijdag 12 juli 2002 01:05 schreef MrX het volgende:
De UNION versie zou zoiets worden:
code:
1
2
3
4
5
6
7
8
9
10
11
SELECT 'user', name as blah
FROM user
WHERE id = 1
 UNION
SELECT 'phone' , number as blah
FROM phone
WHERE user_id = 1
 UNION
SELECT 'dog', name as blah
FROM dog
WHERE user_id = 1
Misschien is mijn SQL wat roestig, maar als ik me niet vergis, is UNION simpelweg een vereniging van verzamelingen (en wordt de resulterende bag dus automatisch een set). Het resultaat hiervan is dus een lijstje met daarin ("Henk", "Bello", "Fifi" "061234567"), waarbij je niet weet of de eigenaar nu "Henk" of "Bello" heet en of "061234567" een hond is.

Daarbij ga je er even van uit dat elke query precies dezelfde tabel als resultaat oplevert (in dit geval een enkel tekstveld), wat in het algemene geval natuurlijk niet waar is.

Verwijderd

Op vrijdag 12 juli 2002 01:10 schreef Soultaker het volgende:

[..]

Misschien is mijn SQL wat roestig, maar als ik me niet vergis, is UNION simpelweg een vereniging van verzamelingen (en wordt de resulterende bag dus automatisch een set). Het resultaat hiervan is dus een lijstje met daarin ("Henk", "Bello", "Fifi" "061234567"), waarbij je niet weet of de eigenaar nu "Henk" of "Bello" heet en of "061234567" een hond is.

Daarbij ga je er even van uit dat elke query precies dezelfde tabel als resultaat oplevert (in dit geval een enkel tekstveld), wat in het algemene geval natuurlijk niet waar is.
Vandaar mijn opmerkingen onder de query:
1) neem een extra kolom op om de waarden te kunnen onderscheiden (in mijn voorbeeld heeft deze kolom resp. de waardes 'user' (1x), 'phone' (3x) en 'dogs' (2x)
2) kan alleen als de types van de waardes gelijk is (in dit geval allemaal char o.i.d., aangezien er een '-' in 1 telefoonnr zit moet dit wel
3) geeft problemen met meer kolommen

Verder gaf ik in een reply daarvoor al aan dat ik het een bagger oplossing vond en de losse queries beter vond, maar ik gaf voor de volledigheid toch even de UNION query oplossing voor dit specifieke geval.

/me gaat nu ECHT naar bed, maar kon dit even niet laten ... so sue me :P

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Soultaker: en wordt de resulterende bag dus automatisch een set
Dat vind ik overigens vervelend: bij de UNION (en INTERSECT en EXCEPT) worden standaard dubbele waarden verwijderd, tenzij je UNION ALL gebruikt, dan worden dubbele waarden niet geelimineerd. Bij de SELECT kan je kiezen voor DISTINCT of ALL, waarbij het default natuurlijk ALL is.

Het zou mij logisch lijken dat je bij UNION ook DISTINCT mag opgeven, maar dat mag dus niet volgens SQL/92. Niet consequent dus.

Ik gebruik als referentie over Date, A Guide to the SQL Standard. Misschien dat de grammatica daarin niet goed is op dit punt, maar dat lijkt me toch onwaarschijnlijk...

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:34
Op vrijdag 12 juli 2002 01:17 schreef MrX het volgende:
Vandaar mijn opmerkingen onder de query:
Ah, die begreep ik inderdaad niet. Zal wel komen omdat het zo'n ongebruikelijke constructie is.
1) neem een extra kolom op om de waarden te kunnen onderscheiden (in mijn voorbeeld heeft deze kolom resp. de waardes 'user' (1x), 'phone' (3x) en 'dogs' (2x)
Wat een ranzige beunoplossing. :r (Sorry; NFI uiteraard)
2) kan alleen als de types van de waardes gelijk is (in dit geval allemaal char o.i.d., aangezien er een '-' in 1 telefoonnr zit moet dit wel
3) geeft problemen met meer kolommen
Niet helemaal waar. Ten eerste kan telefoonnummer best wel een fixed char field zijn (de lengte van een geldig telefoonnummer is beperkt) waarbij een naam misschien wel een varchar/text veld is. Ten tweede kan het ook met meerdere kolommen, maar dan moeten de typen van je kolommen wel hetzelfde zijn.
Verder gaf ik in een reply daarvoor al aan dat ik het een bagger oplossing vond en de losse queries beter vond, maar ik gaf voor de volledigheid toch even de UNION query oplossing voor dit specifieke geval.
Ah, ok, dan zijn we het daar in ieder geval over eens. ;) Meestal laat ik inferieure voorbeelden achterwege, uit angst dat de topicstarter die code overneemt, maar ik denk dat GiLuX wel doorheeft dat 'ie niet met zulke queries aan kan komen zetten.
/me gaat nu ECHT naar bed, maar kon dit even niet laten ...
Welterusten dan!
En laat ik je hier vanavond niet meer zien!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:34
Op vrijdag 12 juli 2002 01:21 schreef mbravenboer het volgende:
Het zou mij logisch lijken dat je bij UNION ook DISTINCT mag opgeven, maar dat mag dus niet volgens SQL/92. Niet consequent dus.
Ik vind wel meer lelijk/inconsequent aan SQL (vooral dat dingen als gebruik van aanhalingstekens niet vastgelegd is, waardoor queries in de regel niet direct portable zijn tussen database servers). Ik zou een complete revisie niet vervelend vinden, waarbij bijvoorbeeld alle namen van tabellen e.d. tussen quotes geplaatst moeten worden (om clashes met toekomstige SQL keywords te voorkomen).
Ik gebruik als referentie over Date, A Guide to the SQL Standard. Misschien dat de grammatica daarin niet goed is op dit punt, maar dat lijkt me toch onwaarschijnlijk...
De PostgreSQL manual zegt ook duidelijk:
query1 UNION [ALL] query2
query1 INTERSECT [ALL] query2
query1 EXCEPT [ALL] query2
ALL is dus optioneel; DISTINCT niet toegestaan.

Ik bedenk trouwens nog een nadeel van de UNION-methode: op deze manier kan een persoon geen hond met dezelfde naam hebben (tenzij je dus weer een extra kolom invoegd).

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Soultaker: ALL is dus optioneel; DISTINCT niet toegestaan.
Dan heeft Date het dus inderdaad goed (verrassend ;) ). Ik heb in m'n eigen grammatica stiekem wel DISTINCT toegelaten, maar ik twijfel nog even of ik deze duidelijke verbetering in stand moet houden ;) . Juist omdat iedereen alles denkt te kunnen verbeteren ontstaan alle dialecten, varianten en uitbreidingen...

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • brammetje
  • Registratie: Oktober 2000
  • Laatst online: 12-01-2025
Op vrijdag 12 juli 2002 00:58 schreef Soultaker het volgende:
In het voorbeeld wat jij geeft, zijn het aantal afzonderlijke queries constant (een query voor de naam van de persoon, een voor zijn honden en een voor zijn telefoonnummers). Het is vaak aantrekkelijk om gegevens 'in bulk' op te vragen, als het aantal afzonderlijke queries hoog op zou kunnen lopen. Hier is dat echter niet het geval; het aantal queries wordt beperkt door het aantal tabellen dat je hebt en niet door de inhoud van die tabellen. Als je honderd personen, duizend telefoonnummers en een miljoen honden in je database hebt, heb je nog steeds maar drie queries nodig om alle gewenste gegevens te verkrijgen.
Op zich ben ik het eens met je verhaal, maar wat je hier doet vind ik een beetje vreemd. Je zegt dat je de de database zoveel mogelijk de data moet laten structureren, maar als jij met drie queries de data op gaat halen dan ga je dus in je code pas relaties leggen? Was dat nou niet waar databases voor bedoeld zijn? Wat ik me nog kan voorstellen is dat je per persoon een querie doet om de telnummers en de honden op te halen. Probleem hierbij is dat je wel ontzettend veel queries krijgt als het aantal personen begint te groeien (of je kan natuurlijk gaan pagen)

Zelf zou ik met 1 join de oplossing gebruiken die ik eerder aangedragen heb, met meerdere zal ik toch meerdere queries gebruiken.

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op vrijdag 12 juli 2002 02:14 schreef brammetje het volgende:
Op zich ben ik het eens met je verhaal, maar wat je hier doet vind ik een beetje vreemd. Je zegt dat je de de database zoveel mogelijk de data moet laten structureren, maar als jij met drie queries de data op gaat halen dan ga je dus in je code pas relaties leggen? Was dat nou niet waar databases voor bedoeld zijn?
Dan lees je over het argument heen dat er eigenlijk helemaal geen relatie is :)
Wat heeft een hond van een persoon met het telefoonnummer van een persoon te maken :?
Ja, ze hebben de persoon gemeen... Maar das een wat rare relatie :)
Wat ik me nog kan voorstellen is dat je per persoon een querie doet om de telnummers en de honden op te halen. Probleem hierbij is dat je wel ontzettend veel queries krijgt als het aantal personen begint te groeien (of je kan natuurlijk gaan pagen)
Stel: join duurt 5ms, en de lichte queries duren elk 1ms...
Waar blijft je argument voor die ene join query dan, behalve dat het één query is ipv drie? :)

Of bedoel je dat je nu met 1000 personen 3000 queries gaat krijgen? Dat is idd wel wat vervelend :+
Zolang je echter niet dergelijke lange overzichten nodig hebt/genereerd zijn de losse queries waarsch een betere oplossing.
Zelf zou ik met 1 join de oplossing gebruiken die ik eerder aangedragen heb, met meerdere zal ik toch meerdere queries gebruiken.
Waar heb jij er een aangedragen dan?
Maar wel beetje rare zin dat :)
Pagina: 1