PHP / MYSQL uitdaging --WHERE kamer_id NOT IN--
Zit even in een 'wak'. Overigens ook mijn eerste post hier.
Ben voor de hobby een reservering site aan het maken, met geringe kennis van PHP en MySQL.
Met google kom je ver, maar het houd een keer op. Soms moet je durven te vragen.
Ik heb een database met twee Tables. Een met de kamers en de info over de kamers.
De andere met te data dat ze bezet zijn.
Nu heb ik hieronder een stukje met code waarbij ik kijk of een kamer vrij is.
Wat ik dus gevonden heb en dat werkt binnen een SQL editor ;
SELECT * FROM Kamerbeheer WHERE kamer_id NOT IN
(
SELECT kamer_id FROM Kamerreservering
WHERE Kamerreservering.datum_stop > '2013-06-30'
AND Kamerreservering.datum_start < '2013-06-16'
)
Maar knoop ik dit in een php, dan krijg ik foutmeldingen:
Warning: mysql_result() [function.mysql-result]: datum_start not found in MySQL result index 4 in /Applications/XAMPP/xamppfiles/htdocs/cisco/reservering.php on line 52
Warning: mysql_result() [function.mysql-result]: datum_stop not found in MySQL result index 4 in /Applications/XAMPP/xamppfiles/htdocs/cisco/reservering.php on line 53
Het zijn de regels :
$res_start =mysql_result($reserveringdb,$r,"datum_start");
$res_stop =mysql_result($reserveringdb,$r,"datum_stop");
Deze komen uit de Table Kamerreservering.
Ik heb zitten puzzelen, maar kom er even niet uit. Ook Google geeft geen antwoord !
De code hieronder wat ik tot nu heb.
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
require "con.php";
$reserveringdb=mysql_query("SELECT * FROM Kamerbeheer WHERE kamer_id NOT IN
(
SELECT kamer_id FROM Kamerreservering
WHERE Kamerreservering.datum_stop > '2013-06-30'
AND Kamerreservering.datum_start < '2013-06-16'
)" );
$res_num=mysql_numrows($reserveringdb);
echo "<table id='res_table'>
<th>Kamer naam</th>";
$r=0;
while ($r < $res_num) {
$res_name =mysql_result($reserveringdb,$r,"Naam");
$res_pers =mysql_result($reserveringdb,$r,"personen");
$res_kid =mysql_result($reserveringdb,$r,"kamer_id");
$res_start =mysql_result($reserveringdb,$r,"datum_start");
$res_stop =mysql_result($reserveringdb,$r,"datum_stop");
echo "<tr><td WIDTH='200px'><b>$res_name</b></td> ";
echo "<td WIDTH='50px'><b>$res_pers</b></td>";
echo "<td WIDTH='50px'><b>$res_kid</b></td>";
echo "<td WIDTH='100px'><b>$res_start</b></td>";
echo "<td WIDTH='100px'><b>$res_stop</b></td></tr>";
$r++;
}
echo "</table>";
?>
require "con.php";
$reserveringdb=mysql_query("SELECT * FROM Kamerbeheer WHERE kamer_id NOT IN
(
SELECT kamer_id FROM Kamerreservering
WHERE Kamerreservering.datum_stop > '2013-06-30'
AND Kamerreservering.datum_start < '2013-06-16'
)" );
$res_num=mysql_numrows($reserveringdb);
echo "<table id='res_table'>
<th>Kamer naam</th>";
$r=0;
while ($r < $res_num) {
$res_name =mysql_result($reserveringdb,$r,"Naam");
$res_pers =mysql_result($reserveringdb,$r,"personen");
$res_kid =mysql_result($reserveringdb,$r,"kamer_id");
$res_start =mysql_result($reserveringdb,$r,"datum_start");
$res_stop =mysql_result($reserveringdb,$r,"datum_stop");
echo "<tr><td WIDTH='200px'><b>$res_name</b></td> ";
echo "<td WIDTH='50px'><b>$res_pers</b></td>";
echo "<td WIDTH='50px'><b>$res_kid</b></td>";
echo "<td WIDTH='100px'><b>$res_start</b></td>";
echo "<td WIDTH='100px'><b>$res_stop</b></td></tr>";
$r++;
}
echo "</table>";
?>
Kamerbeheer
- kamer_id
Kamerreservering
- kamer_id
- datum_stop
- datum_start
Waarschijnlijk nog wel meer, maar die benoem je niet en kan ik dus niet zien. datum_stop en datum_start zijn echter kolommen in kamerreservering en, ik neem aan, niet in kamerbeheer. Als jij dus doet:
SELECT * FROM Kamerbeheer
dan krijg je deze kolommen niet mee. Die staan bestaan namelijk niet in kamerbeheer.
Ten eerste meteen, gebruik nooit 'SELECT *', maar benoem alle kolommen die je wilt selecteren. Niet alleen is het efficienter (=sneller), maar ook zorg je ervoor dat de mysql engine al een foutmelding geeft als je een kolom selecteert die niet in de tabel bestaat.
Ten tweede, als je datum_start en datum_stop nodig hebt, dan moet je aan de slag met joins. En bij joins is het al helemaal geen goed idee om 'SELECT *' te gebruiken, omdat het dan onmogelijk wordt om te weten uit welke tabel een kolom komt als beide tabellen een kolom hebben met dezelfde naam (zoals in jouw geval kamer_id).
Kamerbeheer
id kamer_id Naam personen
1 1 Romeo 8
2 2 Julia 4
3 3 Andrea 2
Kamerreservering
id kamer_id datum_start datum_stop
1 1 01-06-13 01-07-13
2 2 15-06-13 15-07-13
3 4 01-07-13 01-08-13
4 3 10-04-13 20-05-13
Het niet gebruiken van * is wel een bruikbare tip.
De join zal ik gaan zoeken hoe dat moet.
De Selectie of hoe noem je dat? Het werkt wel binnen de SQLEditor, maar niet met PHP.
Zit daar dan een verschil in?
Er is niets mis met je query, dus die query lukt wel. Ook in php lukt je query. Alleen als je kijkt naar de uitkomsten zal je geen datum_start en datum_stop zien.
Dit doet het ...
$reserveringdb=mysql_query("SELECT `Kamerbeheer`.`Naam`, `Kamerbeheer`.`kamer_id`, `Kamerbeheer`.`personen` ,Kamerreservering.`datum_start`, Kamerreservering.`datum_stop`
FROM `Kamerreservering`, `Kamerbeheer`
WHERE Kamerreservering.kamer_id = Kamerbeheer.kamer_id
AND Kamerreservering.datum_stop >= '2013-07-01'
AND Kamerreservering.datum_start <= '2013-07-13'
" );
En nu krijg je een resource terug, geen gegevens.
Beetje raar dat het wel 'werkt'...
Ik denk dat je hier meer aan hebt:
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
26
27
28
29
30
31
32
33
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
27
28
29
30
31
32
33
<?php
// maak de SQL compleet, goed en leesbaar
$sql = "SELECT
kb.Naam,
kb.kamer_id,
kb.personen,
kr.datum_start,
kr.datum_stop
FROM Kamerreservering AS kr
LEFT JOIN Kamerbeheer AS kb
ON kb.kamer_id = kr.kamer_id
AND kr.datum_stop BETWEEN '2013-07-01' AND '2013-07-13'
ORDER BY kr.datum_stop";
// voer de query uit
$res = mysql_query($sql);
// defineer $data altijd, zodat de array altijd bestaat
$data = array();
// kijk of de query gelukt is
if($res !== false)
{
// als die gelukt is, gooi alle gegevens over in $data
// wellicht kan dit ook zo:
// $data = mysql_fetch_assoc($res); ?
while($tmp = mysql_fetch_assoc($res))
{
// voeg toe aan $data
$data[] = $tmp;
}
}
?>
// maak de SQL compleet, goed en leesbaar
$sql = "SELECT
kb.Naam,
kb.kamer_id,
kb.personen,
kr.datum_start,
kr.datum_stop
FROM Kamerreservering AS kr
LEFT JOIN Kamerbeheer AS kb
ON kb.kamer_id = kr.kamer_id
AND kr.datum_stop BETWEEN '2013-07-01' AND '2013-07-13'
ORDER BY kr.datum_stop";
// voer de query uit
$res = mysql_query($sql);
// defineer $data altijd, zodat de array altijd bestaat
$data = array();
// kijk of de query gelukt is
if($res !== false)
{
// als die gelukt is, gooi alle gegevens over in $data
// wellicht kan dit ook zo:
// $data = mysql_fetch_assoc($res); ?
while($tmp = mysql_fetch_assoc($res))
{
// voeg toe aan $data
$data[] = $tmp;
}
}
?>
Als ik dit zie ben ik nog een echte rookie/newbie
Maar heel mooi.. hier kan ik hoop van leren.
Eddy E op 05/03/2013 20:34:57:
Let wel dat $reserveringsdb ook makkelijk false kan woren als er iets mislukt (als er geen records zijn oid...)
Als er geen records zijn krijg je gewoon een resource terug, maar met een lege resultset. Dat is geen mislukte query.
Dat gezegd hebbende, de foutafhandeling verder is desondanks uiteraard wel nuttig, zoniet noodzakelijk.
TS wil de kamers die vrij zijn weten en in jouw query heeft de left join geen enkele zin want de linkertabel is de reservingen en een kamer die niet bestaat kan ook niet gereserveerd worden toch? ;-).
@Andre
Met jouw query krijg je een kamer met een reservering binnen de periode die je opgeeft als onbezet, dwz als kamer1 gereserveerd is van 3 t/m 10 juli die onbezet lijkt.
Om de kamers die vrij zijn te selecteren:
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
SELECT
k.kamer_id,
.........
FROM
kamerbeheer k
LEFT JOIN
(SELECT
kamer_id
FROM
kamerreservering
WHERE
datum_start BETWEEN '2013-07-01' AND '2013-07-13'
OR
datum_eind BETWEEN '2013-07-01' AND '2013-07-13'
OR
(datum_start < '2013-07-01' AND datum_eind > '2013-07-13')
) r
WHERE
r.kamer_id IS NULL
k.kamer_id,
.........
FROM
kamerbeheer k
LEFT JOIN
(SELECT
kamer_id
FROM
kamerreservering
WHERE
datum_start BETWEEN '2013-07-01' AND '2013-07-13'
OR
datum_eind BETWEEN '2013-07-01' AND '2013-07-13'
OR
(datum_start < '2013-07-01' AND datum_eind > '2013-07-13')
) r
WHERE
r.kamer_id IS NULL
Op de ...... de rest van de velden invullen
Gewijzigd op 06/03/2013 18:34:15 door Ger van Steenderen
Ik zoek inderdaad de vrije kamers. Eerste stappen om een reservering site te maken.
Al een beetje met je voorbeeld aan het testen.
Loopt 'vast' op het laatste stukje
WHERE
r.kamer_id IS NULL
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
SELECT kamer_id FROM kamerbeheer
WHERE kamer_id NOT IN
(SELECT
kamer_id
FROM
kamerreservering
WHERE
datum_start BETWEEN '2013-07-01' AND '2013-07-13'
OR
datum_eind BETWEEN '2013-07-01' AND '2013-07-13'
OR
(datum_start < '2013-07-01' AND datum_eind > '2013-07-13')
)
WHERE kamer_id NOT IN
(SELECT
kamer_id
FROM
kamerreservering
WHERE
datum_start BETWEEN '2013-07-01' AND '2013-07-13'
OR
datum_eind BETWEEN '2013-07-01' AND '2013-07-13'
OR
(datum_start < '2013-07-01' AND datum_eind > '2013-07-13')
)
Gewijzigd op 06/03/2013 20:37:45 door Ger van Steenderen