Date range test
Kun je wellicht een dumpje van je testdatabase posten, want ik krijg het op mijn database niet voor elkaar om er iets zinnigs uit te krijgen. Het helpt wellicht ook niet echt dat ik niet precies snap wat ik aan het doen ben.
Alvast bedankt.
Gewijzigd op 18/12/2012 20:24:28 door Lars Anderson
De tabel numbers die Erwin gebruikt heeft ie nu speciaal aangemaakt, maar kan in principe elke tabel in je database zijn, zolang deze maar voldoende records heeft. Er
Een ander addertje onder het gras is het werken met uservars (de @...), ik was even wat aan het vogelen met de query en dan blijkt toch maar weer eens dat uservars in mysql vreemd gedrag vertonen. In dit geval overigens wel te overzien door <= in < te veranderen in de HAVING.
Overigens blijft het wel zo, al zou je elke dag een kamer vrij hebben dat dit niet per definitie dezelfde kamer is. Dus is mijn vraag kunnen gasten een specifieke kamer kiezen?
Gewijzigd op 18/12/2012 20:56:20 door Ger van Steenderen
Nee dat kunnen ze niet. En het is in principe geen probleem om met kamernummers te schuiven.
Aha oké, waarom maak je het jezelf dan zo moeilijk door achteraf het kamernummer toe te wijzen?
Ger van Steenderen op 18/12/2012 17:09:47:
Het punt is dat je anders telkens een tempory table moet gaan maken en daarin de datums te inserten .
Normaal gesproken ben ik ook geen voorstander van zo'n nutteloze tabel, maar of het één er met datums is of met nummers maakt ook niet zoveel uit. Overigens kan jou stukje subquery iets makkelijker:
Normaal gesproken ben ik ook geen voorstander van zo'n nutteloze tabel, maar of het één er met datums is of met nummers maakt ook niet zoveel uit. Overigens kan jou stukje subquery iets makkelijker:
Als ik deze query gebruik dan krijg ik de datums 2012-12-18 tot en met 2012-12-25 i.p.v. 2012-12-17 tot en met 2012-12-24
Toevoeging op 18/12/2012 21:03:21:
Ger van Steenderen op 18/12/2012 21:02:06:
Aha oké, waarom maak je het jezelf dan zo moeilijk door achteraf het kamernummer toe te wijzen?
Omdat het ook een beheersysteem moet worden en er wel zoveel mogelijk aan eventuele wensen tegemoet gekomen moet kunnen worden.
Lars Anderson op 18/12/2012 21:02:15:
Als ik deze query gebruik dan krijg ik de datums 2012-12-18 tot en met 2012-12-25 i.p.v. 2012-12-17 tot en met 2012-12-24
Klopt, zie mijn eerdere opmerking over uservars. Omdat je in de SELECT 1 dag bij de startdatum op telt moet je deze een dag vroeger zetten dan de werkelijke startdatum. Dat er een dag extra bij komt is een mysql kwaaltje, maar op te lossen door de einddatum ook een dag vroeger te zetten of door < te gebruiken ipv <=
Lars Anderson op 18/12/2012 21:02:15:
Omdat het ook een beheersysteem moet worden en er wel zoveel mogelijk aan eventuele wensen tegemoet gekomen moet kunnen worden.
Met andere woorden, gasten kunnen een voorkeur hebben maar dat is alleen als die kamer dan ook daadwerkelijk vrij is.
Wat je kunt doen is dan de eerst beschikbare kamer aan te wijzen als gasten geen voorkeur hebben, en daarvoor een extra kolom aan te maken zodat je achteraf nog kunt schuiven. Leuke uitdaging trouwens.
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
+----+------------+------------+
| id | aankomst | vertrek |
+----+------------+------------+
| 11 | 2013-01-01 | 2013-01-02 |
| 12 | 2013-01-07 | 2013-01-19 |
| 13 | 2013-01-01 | 2013-01-06 |
| 14 | 2013-01-10 | 2013-01-23 |
| 15 | 2013-01-04 | 2013-01-09 |
+----+------------+------------+
| id | aankomst | vertrek |
+----+------------+------------+
| 11 | 2013-01-01 | 2013-01-02 |
| 12 | 2013-01-07 | 2013-01-19 |
| 13 | 2013-01-01 | 2013-01-06 |
| 14 | 2013-01-10 | 2013-01-23 |
| 15 | 2013-01-04 | 2013-01-09 |
+----+------------+------------+
En zoals Ger al zegt is de tabel numbers niets meer dan een 'dummy' tabel. In mijn geval als test (met nog wat meer rijen, maar je begrijpt het nu wel):
Als ik dan de eerder genoemde query run krijg ik deze resultaten:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
+-------------+---------------+
| count(a.id) | date_sequence |
+-------------+---------------+
| 2 | 2013-01-01 |
| 1 | 2013-01-02 |
| 1 | 2013-01-03 |
| 2 | 2013-01-04 |
| 2 | 2013-01-05 |
| 1 | 2013-01-06 |
| 2 | 2013-01-07 |
| 2 | 2013-01-08 |
| 1 | 2013-01-09 |
| 2 | 2013-01-10 |
| 2 | 2013-01-11 |
| 2 | 2013-01-12 |
| 2 | 2013-01-13 |
| 2 | 2013-01-14 |
+-------------+---------------+
| count(a.id) | date_sequence |
+-------------+---------------+
| 2 | 2013-01-01 |
| 1 | 2013-01-02 |
| 1 | 2013-01-03 |
| 2 | 2013-01-04 |
| 2 | 2013-01-05 |
| 1 | 2013-01-06 |
| 2 | 2013-01-07 |
| 2 | 2013-01-08 |
| 1 | 2013-01-09 |
| 2 | 2013-01-10 |
| 2 | 2013-01-11 |
| 2 | 2013-01-12 |
| 2 | 2013-01-13 |
| 2 | 2013-01-14 |
+-------------+---------------+
Overigens zag ik nu wel wat Ger bedoelde met die aanpassing in de HAVING clause. Dat moet inderdaad een < teken zijn in plaats van <=. Dat was me eerder niet opgevallen, dus zeker geen probleem dat je er nog even tussen kwam Ger.
Alleen gebruik ik een OUTER JOIN (in jouw situatie een right) zodat je ook de datums waarop geen kamer gereserveerd is meekrijgt.
Aan de andere kant, voor de specifieke vraag maakt het niet uit. Wat hij wil weten is of er een dag is waarop alle kamers zijn gereserveerd. Hij wil dus het maximum hebben en alle nullen zouden dus in feite weggelaten kunnen worden.
@Lars
Dus om te weten of in een bepaalde periode een kamertype niet beschikbaar is, kan dan een HAVING COUNT(id)=2 aan de GROUP BY worden toegevoegd.
Krijg je rijen terug uit de query is een kamertype niet beschikbaar.
Optie 1:
Geeft het maximaal aantal boekingen op een dag binnen de gekozen periode weer. Deze kan ik dan vervolgens vergelijken met de het aantal beschikbare kamers.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
SET @num = -1;
SELECT MAX(c) AS max_occupied
FROM (
SELECT count(a.id) as c, b.date_sequence
FROM booking a
INNER JOIN (
SELECT DATE_ADD( '2013-01-01', interval @num := @num+1 day) AS date_sequence
FROM numbers
HAVING DATE_ADD('2013-01-01', interval @num day) <= '2013-01-14'
) b
ON (
a.aankomst <= b.date_sequence
AND vertrek > b.date_sequence
)
GROUP BY b.date_sequence
)
as d
?>
SET @num = -1;
SELECT MAX(c) AS max_occupied
FROM (
SELECT count(a.id) as c, b.date_sequence
FROM booking a
INNER JOIN (
SELECT DATE_ADD( '2013-01-01', interval @num := @num+1 day) AS date_sequence
FROM numbers
HAVING DATE_ADD('2013-01-01', interval @num day) <= '2013-01-14'
) b
ON (
a.aankomst <= b.date_sequence
AND vertrek > b.date_sequence
)
GROUP BY b.date_sequence
)
as d
?>
Optie 2:
Geeft de dagen weer waarop er $max_rooms of meer kamers (in geval van handmatige overboekingen) gereserveerd zijn. Wanneer deze query GEEN resultaat heeft zijn er nog kamers beschikbaar. >1 resultaten betekent dat een reservering niet mogelijk is in de gekozen periode omdat er op minimaal 1 dag van de gekozen periode te weinig kamers beschikbaar zijn.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
SET @num = -1;
SELECT count(a.id) as c, b.date_sequence
FROM booking a
INNER JOIN (
SELECT DATE_ADD( '2013-01-01', interval @num := @num+1 day) AS date_sequence
FROM numbers
HAVING DATE_ADD('2013-01-01', interval @num day) <= '2013-01-14'
) b
ON (
a.aankomst <= b.date_sequence
AND vertrek > b.date_sequence
)
GROUP BY b.date_sequence
HAVING COUNT(id) >= " . $max_rooms . "
?>
SET @num = -1;
SELECT count(a.id) as c, b.date_sequence
FROM booking a
INNER JOIN (
SELECT DATE_ADD( '2013-01-01', interval @num := @num+1 day) AS date_sequence
FROM numbers
HAVING DATE_ADD('2013-01-01', interval @num day) <= '2013-01-14'
) b
ON (
a.aankomst <= b.date_sequence
AND vertrek > b.date_sequence
)
GROUP BY b.date_sequence
HAVING COUNT(id) >= " . $max_rooms . "
?>
Hebben jullie nog een voorkeur voor welke methode ik het beste kan gebruiken. Of is het om het even?
De tweede methode lijkt mij veruit het makkelijkste, omdat je dan alleen hoeft controleren of je resultaat terug krijgt (of niet)
Nogmaals bedankt voor alle hulp.