Toon posts:

[MYSQL] x van een NULL waarde aftrekken

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb dus een mysql database hieronder staat een model van de 2 tabellen waar het om gaat:
Afbeeldingslocatie: http://www.thekip.nl/pdm.JPG

ik wil dus berekenen hoeveel plaatsen er nog op een bepaalde datum en tijd vrij zijn (dat tijd geen timestamp is weet ik en daar zit een idee achter). Hiervoor heb ik de volgende query maar die geeft constant NULL terug terwijl de 2 query's los van elkaar wel werken (dus 1 voor booking en 1 voor regatta).

De query die ik zelf heb:

code:
1
2
3
4
SELECT (regatta.max_crew - IFNULL(SUM(booking.slots),0))
FROM booking, regatta
WHERE booking.regatta_date = 'datum' AND regatta.regatta_date = 'datum' AND
booking.regatta_time = 'tijdindicatie' AND regatta.regatta_time = 'tijdindicatie';


MYSQL is niet mijn sterkste punt maar ik zit nu echt vast, en de mysql handleiding helpt me ook niet verder. Ik dacht zelf eigenlijk dat booking.regatta_time = regatta.regatta_time = 'tijdindicatie' ook mocht maar dat werkt helemaal niet :/

ik werk overigens tot 3 uur (zit op sint maarten) dus kan pas morgen reageren ivm geen internet op kamer...

[ Voor 9% gewijzigd door Verwijderd op 13-10-2005 20:57 ]


Verwijderd

Je zou eens kunnen beginnen met je query wat duidelijke te schrijven:

code:
1
2
3
4
5
6
7
8
9
SELECT 
  (regatta.max_crew - IFNULL(SUM(booking.slots),0))
FROM 
  booking, regatta
WHERE 
  booking.regatta_date = 'datum' AND 
  regatta.regatta_date = 'datum' AND
  booking.regatta_time = 'tijdindicatie' AND 
  regatta.regatta_time = 'tijdindicatie'


Verder.. waarom heb je 2 velden regatta_time? Waarom een samengestelde ID in de 2e tabel?

als laatste, je gebruikt sum, een aggregate functie, maar ik zie geen group by?

Volgens mij kun je het beter zo doen:

tabel1:
booking_id int (autoinc,pk)
regatta_id int (fk)
cust_id int
slots int

tabel2:
regatta_id int (autoinc,pk)
max_crew int

[ Voor 23% gewijzigd door Verwijderd op 13-10-2005 21:21 ]


Verwijderd

Als er geen matching rijen zijn (bv. een regatta waarvoor geen boekingen gedaan zijn?), dan komt er denk ik geen data uit je query. Dat verklaart dan je NULL.

Wellicht dat je met een LEFT JOIN aan de slag kunt. Je zorgt er dan voor dat er in ieder geval data geretourneerd wordt als er geen boekingen zijn voor een regatta. Bijvoorbeeld:
code:
1
2
3
SELECT [iets]
  FROM regatta LEFT JOIN booking USING (regatta_date, regatta_time)
  WHERE regatta.regatta_date = 'datum' AND regatta.regatta_time = 'tijdindicatie'
Je moet nu alleen nog even zoeken wat de juiste [iets] is om te SELECTeren :)

Ik weet niet of je twee losse queries kunt gebruiken? Dan zou ik eerst proberen de max_crew op te vragen van de betreffende regatta, en daarna los de SUM() van alle relevante slots. Deze kun je dan zelf makkelijk van elkaar aftrekken.

[ Voor 4% gewijzigd door Verwijderd op 13-10-2005 21:22 ]


Verwijderd

Verwijderd schreef op donderdag 13 oktober 2005 @ 21:18:
als laatste, je gebruikt sum, een aggregate functie, maar ik zie geen group by?
Een SUM zonder GROUP BY groepeert automatisch naar alle rijen.

Wellicht is de [iets] uit mijn vorige post gewoon
code:
1
max_crew - SUM(IFNULL(slots,0))
Let op het omgedraaide SUM en IFNULL.

[ Voor 35% gewijzigd door Verwijderd op 13-10-2005 21:29 ]


Verwijderd

ah you're right.. even overheen gekeken.

Wat betreft de join, hij kan een outer join gebruiken.

[ Voor 4% gewijzigd door Verwijderd op 13-10-2005 21:26 ]


Verwijderd

Topicstarter
Verwijderd schreef op donderdag 13 oktober 2005 @ 21:19:
Als er geen matching rijen zijn (bv. een regatta waarvoor geen boekingen gedaan zijn?), dan komt er denk ik geen data uit je query. Dat verklaart dan je NULL.

Wellicht dat je met een LEFT JOIN aan de slag kunt. Je zorgt er dan voor dat er in ieder geval data geretourneerd wordt als er geen boekingen zijn voor een regatta. Bijvoorbeeld:
code:
1
2
3
SELECT [iets]
  FROM regatta LEFT JOIN booking USING (regatta_date, regatta_time)
  WHERE regatta.regatta_date = 'datum' AND regatta.regatta_time = 'tijdindicatie'
Je moet nu alleen nog even zoeken wat de juiste [iets] is om te SELECTeren :)

Ik weet niet of je twee losse queries kunt gebruiken? Dan zou ik eerst proberen de max_crew op te vragen van de betreffende regatta, en daarna los de SUM() van alle relevante slots. Deze kun je dan zelf makkelijk van elkaar aftrekken.
Deze oplossing lijkt te werken, ik had al gekeken bij een left join maar ik kreeg hem niet goed toegepast. Bedankt voor de hulp :)

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08:14

Janoz

Moderator Devschuur®

!litemod

dat de tijd geen timestamp is weet ik en daar zit een idee achter
Hmm, spannend. Welk idee?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

sowieso is imo het design van de database een beetje smerig. Een samengestelde primary key, waar dan ook nog eens een varchar veld inzit van lengte 3 (?) en die dan 'time' genoemd wordt.

Hoe kom je aan die waarde 3? Ik kan geen methode bedenken waarbij je 3 tekens nodig hebt om een tijd aan te geven? 1:00 is 1 uur 's middags, dat zou als 100 kunnen, maar hoe doe je dan 14:00?

Waarom niet gewoon een time(), timestamp of datetime veld?

Je ziet ook terug in je design dat het niet klopt, omdat je nu dat date en tijd veld 2 keer in je database hebt staan.

Het is echt netter, voor queries makkelijker en voor de performance beter, om de tabel regatta een eigen unieke autoinc integer id te geven.

[ Voor 33% gewijzigd door Verwijderd op 14-10-2005 14:17 ]


  • Tijgertje84
  • Registratie: Augustus 2005
  • Laatst online: 04-06-2025
lol wel grappig om te zien dat jij hier ook een post neer zet hans :)
greetz uit holland
Roy @ Finntax :P

[ Voor 5% gewijzigd door Tijgertje84 op 14-10-2005 15:13 ]

Intel© Conroe E6600 | Asus P5Q PRO Turbo | Sapphire Vapor-X HD5770 1GB | G.E.I.L. 2 GB DDR2-667 Kit CL4 4-4-12 | WD Caviar SE16 2x250GB (S-ATA2) (Raid0) | Sunbeam Trio | Chaintec CFT-500A | Windows XP Pro SP3 | Samsung Syncmaster S23A350H


Verwijderd

Topicstarter
zou een id beter zijn dan deze primary key? Ik heb altijd geleerd dat wanneer je het zo uniek kan maken dat je het beter zo kan doen.

edit:
na een keer de query herschrijven werkt hij ineens wel :)

btw die tijd is omdat er 2 entries op die tijd moeten zijn en de tijden staan altijd vast en daardoor is het makkelijker om een varchar te gebruiken ipv een timestamp ivm vergelijken enzo :)

[ Voor 50% gewijzigd door Verwijderd op 14-10-2005 17:43 ]


Verwijderd

Ik denk dat je je in de praktijk niet zo druk hoeft te maken om je primary key. Alleen als je echt een grote database gaat maken of veel concurrent access krijgt wordt performance belangrijk. Anders doe je het gewoon zoals je het zelf makkelijk vindt :)

Soms maakt een aparte key de queries weer lastiger, omdat je de key moet vergelijken, maar de gebruiker bijvoorbeeld met de strings werkt. Bijvoorbeeld een (string) username versus (numerieke) userid.

Ik gebruik dan ook wel eens gewoon strings als primary/foreign keys.

Overigens wordt een autonumber in mysql niet automatisch gereset, dus als je een 32-bit integer hebt en die op 2 of 4 miljard (ongeveer) uitkomt dan kun je geen nieuwe records meer toevoegen. Zal ook wel niet zo'n vaart lopen in de praktijk, maar je weet nooit... :)

Verwijderd

Topicstarter
Verwijderd schreef op vrijdag 14 oktober 2005 @ 19:50:
Overigens wordt een autonumber in mysql niet automatisch gereset, dus als je een 32-bit integer hebt en die op 2 of 4 miljard (ongeveer) uitkomt dan kun je geen nieuwe records meer toevoegen. Zal ook wel niet zo'n vaart lopen in de praktijk, maar je weet nooit... :)
Dit verwacht ik inderdaad niet maar het is uiteraard een aandachtspunt, voor zon grote database zou ik denk ik ook geen mysql gebruiken:)

Verwijderd

Of je gebruikt geen 32-bit int voor je id, kan ook natuurlijk, afhankelijk van hoeveel records je verwacht.

Strings als primary of foreign key is gewoon extreem smerig imo. Daarnaast is het de dood voor je performance.

Kijk nu eens naar dit voorbeeld.. deze key vertraagt niet alleen de database onnodig, maar maakt het ook nog eens nodig dat je in elke tabel waar deze key een FK is, twee velden opneemt.

Zowel qua performance, als qua netheid, is een autoinc ID in dit geval gewoon beter.
btw die tijd is omdat er 2 entries op die tijd moeten zijn en de tijden staan altijd vast en daardoor is het makkelijker om een varchar te gebruiken ipv een timestamp ivm vergelijken enzo
Dan gebruik je toch gewoon een time veld? Die ziet er zo uit bv: "10:00".

En waarom gebruik je dan nu een varchar(3)? Hoe ga jij 11:59 als tijd in 3 chars zetten?

Verder: wat bedoel je met 'er moeten 2 tijden zijn'? Zit je nu velden uit elkaar te trekken en er primary keys van te maken, omdat het dan makkelijker is ze te vergelijken? Had je die tabel dus ook zo kunnen doen:

regatta
regatta_datetime datetime (pk)
max_crew

Als dit echt het geval is, alsjeblieft, ga niet die kant op. Doe het goed, of doe het niet ;)

[ Voor 46% gewijzigd door Verwijderd op 14-10-2005 23:07 ]


  • Apache
  • Registratie: Juli 2000
  • Laatst online: 28-04 15:52

Apache

amateur software devver

Verwijderd schreef op vrijdag 14 oktober 2005 @ 19:50:
Ik denk dat je je in de praktijk niet zo druk hoeft te maken om je primary key. Alleen als je echt een grote database gaat maken of veel concurrent access krijgt wordt performance belangrijk. Anders doe je het gewoon zoals je het zelf makkelijk vindt :)
En zo krijg je slecht onderhoudbare systemen waarbij heel wat meer overhauled moet worden, schaalbaarheid sterk te wensen over laat en waardoor veel informatica projecten een steeds grotere kostenpost worden naarmate de tijd, eisen en aantal gebruiker evolueren.

De moderne gedachtes gaan toch meer naar het UP & communality & variability analyse, daarbij zal je zo'n zaken niet laten liggen en het gewoon doen zoals je zelf wil maar wat het systeem vereist, ook naar de toekomst toe.

If it ain't broken it doesn't have enough features


Verwijderd

Apache schreef op zaterdag 15 oktober 2005 @ 15:27:
En zo krijg je slecht onderhoudbare systemen waarbij heel wat meer overhauled moet worden, schaalbaarheid sterk te wensen over laat en waardoor veel informatica projecten een steeds grotere kostenpost worden naarmate de tijd, eisen en aantal gebruiker evolueren.
offtopic:
Of je doet het met agile methoden zoals eXtreme Programming. Wat het systeem vereist is niet altijd de ultieme performance en schaalbaarheid (wat weer niet wil zeggen dat je er niet naar MAG kijken).

Zulke kostenposten komen ook vaak voort uit de angst voor het weggooien van 'oude troep'. Hierdoor wordt er op een systeem constant voortgeborduurd met pleisters op pleisters, totdat niemand er meer iets van snapt. Refactoring naar aangepaste eisen/kennis is erg belangrijk, maar vereist in veel organisaties enorme durf (en terecht: het risico is vaak inmiddels ook erg groot geworden).

Van te voren heel lang nadenken heeft vaak ook tot gevolg dat het ontwikkeltraject in te kort tijdsbestek gepropt moet worden (waarbij bijvoorbeeld te weinig tijd voor testen overblijft). Gevolg: slechte software; en bovendien veranderen de eisen in de loop van de tijd toch vrijwel altijd, zodat het ondanks al dat nadenkwerk alsnog opnieuw moet :)

Mjah, de waarheid zal wel ergens in het midden liggen...
daarbij zal je zo'n zaken niet laten liggen en het gewoon doen zoals je zelf wil maar wat het systeem vereist, ook naar de toekomst toe.
offtopic:
Helemaal mee eens. Als je makkelijk de performance/schaalbaarheid/etc. mee kunt nemen in je werk doe je dat natuurlijk. Maar je gaat niet als een blinde je werk optimizen voor wat performance die je niet nodig hebt [binnen afzienbare tijd].
Pagina: 1