Record tussenvoegen in database indien mogelijk.
BIJV:
drie tijdranges begintijd-eindtijd op datum1
twee tijdranges begintijd-eindtijd op datum2
een tijdrange begintijd-eindtijd op datum3
datum1: 09:00-11:30 13:00-15:00 20:00-22:30
datum2: 09:00-11:30 20:00-22:30
datum3: 13:00-15:00
Ik wil nu bijv een record met daarin 13:00-15:00 toevoegen op deze drie datums als dat kan, anders niet.
Op datum1 en datum3 gaat dat niet (bezet), maar wel op datum2 (range is nog vrij).
datum2 moet dus worden:
datum2: 09:00-11:30 13:00-15:00 20:00-22:30
de andere datums blijven ongewijzigd,
Hoe kan ik dit makkelijk doen?
Ik heb geprobeerd in een while steeds een record te lezen dan te bepalen of het record met de nieuwe range past, maar kan dat niet bepalen. Ik heb geprobeerd eerst alle records van eenzelfde datum te lezen en die in een variabele zetten en dan te bepalen of het nieuwe record met de gegeven tijdrange past, maar kom daar als beginner niet uit.
Wie kan helpen?
Bvd
Kijk eerst eens naar normaliseren.
Mvg.
Er is geen mogelijkheid om dit op een bepaalde plaats in te voegen.
De volgorde waarin je de records terug krijgt bij het uitlezen bepaal je m.b.v. voorwaarden en evt sorteer sleutels en sorteervelden bij het uitlezen.
Het betreft ook alleen maar een INSERT als het om een record op een nieuwe datum gaat; en op die datum kan ik sorteren waardoor ik de records van die datum op een tabelregel in beeld kan brengen.
Ik hoop dat je me begrijpt, nu nog het antwoord op mijn vraag.
mvg
Hoe is je database tabel nu opgebouwd? Welke kolommen heb je?
In de betreffende tabel staat oa de datum waarvoor een erin opgenomen record geldt plus een aanvangs- en eindtijd (zie eerste bericht). De vraag is nu hoe ik een nieuw record voor diezelfde datum WEL kan invoeren als dat in dezelfde tijdrange past en NIET als het niet past.
De records worden eerst gesorteerd op oplopende datum en daarbinnen op oplopende tijdranges. In een while lees is dus steeds een record van een zelfde datum maar steeds met een andere tijdrange per record. Ik wil nu een record toevoegen met diezelfde datum en met dezelfde tijdrange als dat op die datum past.
Ik kan het niet duidelijker maken vrees ik. ZIe eerste bericht nog eens aub.
mvg
Quote:
Ik kan het niet duidelijker maken vrees ik
Ik vrees van wel ;-)
Je hebt dus nu 1 kolom waar een datum in staat en 1 kolom waar (als tekst??) een aanvangstijd en eindtijd in staat?
Om het maar heel bot te zeggen: gooi dat maar gelijk weg als dat zo is.
Maak er 2 kolommen van:
- aanvangmoment (datetime)
- eindmoment (datetime)
Elke regel in je tabel is dan 1 moment met een beginmoment (datum + tijd) en een eindmoment (datum + tijd).
Als je er een regel bij wil invoegen, controleer je eerst (bijvoorbeeld met SELECT query) of je 'nieuwe periode' al een andere periode overlapt. Zo ja; foutmelding laten zien, zo nee; insert query
Gewijzigd op 22/08/2014 13:55:36 door Ramon van Dongen
Ik heb dus nu 1 kolom waar een datum in staat, 1 kolom waar (als tekst) een aanvangstijd in staat en nog een kolom waar de eindtijd (als tekst) in staat.
Elke regel in de tabel is dan 1 moment met een beginmoment (datum + tijd) en een eindmoment (datum + tijd).
Als ik op een zelfde datum een regel bij wil invoegen, controleer ik eerst of de 'nieuwe periode' al een andere periode (op die dag) overlapt. Zo ja; foutmelding laten zien, zo nee; insert query.
En daar zit nu het probleem want dan moet ik dus alle periodes tegelijk hebben om dat te kunnen checken. Moet ik dan info uit de vorige regel (record) steeds bewaren of hoe doe je dat? Als ik geen 'totaalbeeld' van een dag heb kan ik ook niet zien of de gewenste periode vrij of bezet is, toch??
mvg
periode_ID | aanvangmoment | eindmoment
----------------------------------------------------------------------------
1 | 2014-08-22 14:15:00 | 2014-08-22 15:00:00
2 | 2014-08-22 15:05:00 | 2014-08-22 15:15:02
3 | 2014-08-23 00:00:00 | 2014-08-23 01:00:00
4 | 2014-08-22 16:00:00 | 2014-08-22 16:20:00
Vervolgens wil je de periode 2014-08-22 14:10:00 tot 2014-08-22 14:20:00 invoeren.
Dan ga je dus controleren of er in dat tijdsbestek nog niets is.
Helemaal voorkauwen is niet leuk, dus hoe zou je zo'n controle zelf bedenken. Denk aan momenten vergelijken met bijvoorbeeld BETWEEN (SQL functie) of groter dan > of kleiner dan < in de WHERE.
Gewijzigd op 22/08/2014 14:20:11 door Ramon van Dongen
Let op, gesorteerd op oplopende datum en daarbinnen op oplopende tijd:
periode_ID | datum | aanvangmoment | eindmoment
----------------------------------------------------------------------------
1 | 2014-08-22 | 14:15:00 | 15:00:00
2 | 2014-08-22 | 15:05:00 | 15:15:02
3 | 2014-08-22 | 16:00:00 | 16:20:00
4 | 2014-08-23 | 00:00:00 | 01:00:00
Vervolgens wil je de periode 2014-08-22 14:10:00 tot 2014-08-22 14:20:00 invoeren.
Dan ga je dus controleren of er in dat tijdsbestek nog niets is.
Inderdaad en dat is nu hetgeen er niet wil lukken, omdat je dan eigenlijk alle records van één dag tegelijk moet hebben om te bekijken. Bij elke doorgang van de while-loop wordt er steeds één record gelezen en is de vorige weer weg. en heb ik de volgende nog niet. Moet ik dan de info uit de vorige steeds bewaren? Het is zuiver een programmeerprobleempje en geen database-issue.
mvg
Volgens mij kan het in 1 query, waarbij je controleert of voor de betreffende datum de begintijd valt tussen een reeds bestaand aanvangmoment en eindmoment en controleert of er de eindtijd valt tussen een reeds bestaand aanvangmoment en eindmoment. de WHERE krijgt dus meerdere voorwaarden om te controleren.
Als je resultaat 0 rijen oplevert, zit je volgens mij goed.
Hoe vraag je nu de gegevens op/controleer je?
Gewijzigd op 22/08/2014 15:41:27 door Obelix Idefix
Quote:
Hoe het in de database staat, op welke volgorde, is totaal niet van belang. Al staan er 10.000 periodes in, helemaal door elkaar, maakt voor de database niks uit.Let op, gesorteerd op oplopende datum en daarbinnen op oplopende tijd:
Quote:
Sterker nog; niet alleen van die dag, maar van alle dagen. Een periode kan namelijk ook van 23:00 tot 01:00 uur zijn en dan is het eindmoment dus niet op dezelfde dag als het beginmoment.omdat je dan eigenlijk alle records van één dag tegelijk moet hebben om te bekijken.
Quote:
Welke while-loop?Bij elke doorgang van de while-loop wordt er steeds één record gelezen en is de vorige weer weg.
Code (php)
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
// je db connectie
$mysqli = mysqli_connect($host,$user,$pass,$dbas) or die("Fout: ".mysqli_error($mysqli));
// deze gegevens komen uiteindelijk uit een formulier waarschijnlijk, nu even zo
$aanvang = '2014-08-22 14:10:00';
$einde = '2014-08-22 14:20:00';
$controle = $mysqli->query("
SELECT
periode_ID
FROM
periodes
WHERE
aanvangsmoment BETWEEN '".mysqli_real_escape_string($mysqli,$aanvang)."' AND '".mysqli_real_escape_string($mysqli,$einde)."'
OR eindmoment BETWEEN '".mysqli_real_escape_string($mysqli,$aanvang)."' AND '".mysqli_real_escape_string($mysqli,$einde)."'
");
if(mysqli_num_rows($controle)) == 0){
echo 'periode is nog vrij dus lekker invoeren!';
}
else{
echo 'periode niet vrij!';
}
?>
// je db connectie
$mysqli = mysqli_connect($host,$user,$pass,$dbas) or die("Fout: ".mysqli_error($mysqli));
// deze gegevens komen uiteindelijk uit een formulier waarschijnlijk, nu even zo
$aanvang = '2014-08-22 14:10:00';
$einde = '2014-08-22 14:20:00';
$controle = $mysqli->query("
SELECT
periode_ID
FROM
periodes
WHERE
aanvangsmoment BETWEEN '".mysqli_real_escape_string($mysqli,$aanvang)."' AND '".mysqli_real_escape_string($mysqli,$einde)."'
OR eindmoment BETWEEN '".mysqli_real_escape_string($mysqli,$aanvang)."' AND '".mysqli_real_escape_string($mysqli,$einde)."'
");
if(mysqli_num_rows($controle)) == 0){
echo 'periode is nog vrij dus lekker invoeren!';
}
else{
echo 'periode niet vrij!';
}
?>
@Ramon: in zijn database staat datum in een ander veld dan aanvang- / eindtijd (zie post Andre Janssen 22/08/2014 14:51:11).
En alle tijden bij elkaar gemoffeld in 1 record als string.
Dat heb ik dus al aangegeven dat het dan nooit gaat werken en het alleen werkt als zijn database tabel op een andere manier ingericht is.
1. Eigenlijk is jouw oplossing ook een (verkapte) loop, maar dan over de hele tabel 'periodes'.
2. Een periode kan in mijn geval alleen op een één datum vallen, de dag eindigt om 12 uur 's nachts.
Een periode loopt dus niet over naar de volgende dag.
3. De datum staat in een apart veld. Maar dat is niet zo'n probleem denk ik.
4. Het feit dat de te plaatsen periode niet past binnen een van de reeds aanwezigen wil niet zeggen dat die daarbuiten dus wél past.
Ik heb het idee dat jouw oplossing zer zeker in de goede richting wijst. Als beginner schrijf ik eea nog niet zo compact als jij maar gebruik ik meer statements.
Feit is volgens mij wel dat jij de hele database afzoekt, terwijl ik alleen de records van een bepaalde datum check hetgeen natuurlijk sneller gaat, lijkt me. De datum moet dus op een of andere manier in de query worden verwerkt?
Misschein is dat wat 'Obelix en Idefix' bedoelt?
mvg
Andre Janssen op 22/08/2014 16:11:17:
3. De datum staat in een apart veld. Maar dat is niet zo'n probleem denk ik.
Waarom?
Dat is alleen maar onhandig.
Nee, "alle tijden bij elkaar gemoffeld in 1 record als string": dat is niet zo.
datum, aanvangstijd en eindtijd zijn aparte velden!
In jouw scriptje zou ik de datum er bijv. gewoon bij kunnen zetten.
Maar blijft de wens om niet de hele tabel te moeten doorspitten, immers de records zijn al gesortreerd op datum en daarbinnen op tijd (zie eerdere reacties).
mvg
Andre Janssen op 22/08/2014 16:11:17:
Hoi Ramon,
1. Eigenlijk is jouw oplossing ook een (verkapte) loop, maar dan over de hele tabel 'periodes'.
1. Eigenlijk is jouw oplossing ook een (verkapte) loop, maar dan over de hele tabel 'periodes'.
Hoezo een loop?
Andre Janssen op 22/08/2014 16:11:17:
3. De datum staat in een apart veld. Maar dat is niet zo'n probleem denk ik.
Daarmee maak je het jezelf lastiger. Maar als dat geen probleem is.... ;-)
Andre Janssen op 22/08/2014 16:11:17:
4. Het feit dat de te plaatsen periode niet past binnen een van de reeds aanwezigen wil niet zeggen dat die daarbuiten dus wél past.
Die moet je me even uitleggen. Waarom zou die niet passen?
Andre Janssen op 22/08/2014 16:11:17:
Als beginner schrijf ik eea nog niet zo compact als jij maar gebruik ik meer statements.
Weet niet hoe je veel meer statements nodig hebt, maar laat eens zien wat je hebt.
Andre Janssen op 22/08/2014 16:11:17:
Feit is volgens mij wel dat jij de hele database afzoekt, terwijl ik alleen de records van een bepaalde datum check
hetgeen natuurlijk sneller gaat, lijkt me.
hetgeen natuurlijk sneller gaat, lijkt me.
En die records staat toch in dezelfde database als de database die Ramon doorzoekt?
Alleen ga jij op drie velden zoeken (datum, aanvang, eind) en Ramon op twee velden. Mag jij raden wat sneller is.... ;-)
Andre Janssen op 22/08/2014 16:22:01:
Maar blijft de wens om niet de hele tabel te moeten doorspitten, immers de records zijn al gesortreerd op datum en daarbinnen op tijd (zie eerdere reacties).
Volgens mij maak je een denkfout. Een database is er, mits goed opgezet, voor bedoeld om heeeeeeel veeeeel informatie te bevatten en die heel snel te tonen, zodra er om gevraagd wordt. Een database zal per definitie helemaal doorlopen moeten worden om alle resultaten te tonen. Of je de manier van Ramon gebruikt of jouw manier.
Verder is het niet mogelijk om een record toe te voegen tussen bestaande records. Een nieuw record wordt (automatisch) toegevoegd aan het einde van een tabel.
Records en tijden zijn dus niet gesorteerd.
Geen idee waar jij dat idee vandaan haalt.
Maar met een goede database-opzet, maakt de volgorde ook niet uit.
Immers in Ramon's scriptje kan ik de betreffende datum toch gewoon in $aanvang en $einde vooraan toevoegen?
4: Het feit dat de te plaatsen periode niet past binnen een van de reeds aanwezigen wil niet zeggen dat die daarbuiten dus wél past.
Het gaat er niet om om een vrije range te vinden maar om exact op dezelfde (vrije?) range te kunnen plaatsen.
5: Feit is volgens mij wel dat jij de hele database afzoekt, terwijl ik alleen de records van een bepaalde datum check hetgeen natuurlijk sneller gaat, lijkt me.
Ik kijk toch alleen maar in de records van eenzelfde datum, in dit geval twee op '2014-08-22'.
Immers mijn query sorteert de records op datum en daarabinnen op tijd.
Natuurlijk wordt een record ge-INSERT maar ik kan ze daarna SORTeren waarop ik wil, in dit geval op datum en daarbinnen op tijd. Daarna kan het in het resultaat van de query het ingevoerde record ahw 'ertussen' staan op dezelfde datum en een andere tijdrange. Het is maar hoe je het bekijkt denk ik.
In elk geval fijn dat jullie zo snel reageren en ik denk dat het scriptje zeer bruikbaar is.
mvg
Toevoeging op 22/08/2014 16:56:06:
mijn query ziet er alsvolgt uit:
rsv_sesdat is de sessiedatum
rsv_tot is de eindtijd
De rest zal wel duidelijk zijn hoop ik.
$query = ('SELECT * FROM ' . "$rsv_tabel" . " WHERE (rsv_sesdat = '$extrajjjjmmdd') ORDER BY rsv_sesdat ASC, rsv_tot ASC" );
mvg
Hele database afzoeken; voor database een fluitje van een cent
Periode kan maar op één datum zijn; maakt met mijn script niet uit
Datum en tijden apart opslaan: de problemen ondervind je nu al en worden alleen maar erger.
Maar je moet het zelf weten.