Beste php-ers,

Voor een online boekingssysteem ben ik een grafiek aan het maken met het aantal boekingen per jaar. Hierdoor kan inzicht verkregen worden of de boekingen van het nieuwe jaar op schema liggen.

Nu vraagt de grafiek om een xml formaat waar ik per week het aantal boekingen wil 'invullen'. ue.datum is opgeslagen als DATETIME formaat.

Per week draai ik de volgende query:

<?php
$weken = range(1,53);
$jaar = 2013;
$aantal = 0;
foreach($weken as $week):
$sql = '
SELECT
COUNT(ue.id) AS aantal
FROM
user_event AS ue
INNER JOIN
event AS e ON ue.event = e.id
WHERE
(DATE_FORMAT(e.start, \'%Y\') = '.$jaar.')
AND
(DATE_FORMAT(ue.datum, \'%V\') = '.$week.')';
//query uitvoeren
//row ophalen en bij aantal optellen dus bijvoorbeeld: $aantal = $aantal + $row;
endforeach;
?>

Als ik ter controle het volgende doe krijg ik net iets meer resultaten.

<?php
$sql = '
SELECT
COUNT(ue.id) AS aantal
FROM
user_event AS ue
INNER JOIN
event AS e ON ue.event = e.id
WHERE
(DATE_FORMAT(e.start, \'%Y\') = '.$jaar.')';
?>

En dat kan niet de bedoeling zijn, op beide methoden moet ik evenveel boekingen kunnen behalen in dat bepaalde jaar. Kan iemand misschien een tip geven waarom ik cumulatief per week minder resultaten heb dan wanneer ik het allemaal in één keer selecteer? Ik ben aardig door het ISO date format gestruind en dan zie je dat ze een week 53 gebruiken. Verder zie ik geen bijzonderheden. Iemand een tip voor een andere aanpak of een effectieve methode?

Crispijn

edit
Ik bouw het hele project in Zend Framework en het totaal beslaat aardig wat code dat hier niet relevant is volgens mij, dit is de basis opzet die volgens mij ergens fout gaat. Mocht er behoefte zijn aan meer broncode dan hoor ik het graag!
Verander de WHERE eens in:
[code lang="SQL"]
WHERE ue.datum BETWEEN "2013-01-01" AND "2013-12-31"
[/code]
Ik weet niet welke data er in de gejoinde tabellen staat dus het is een beetje lastig te beoordelen waar het fout gaat.
Dat zou met die LEFT joins toch niet uit moeten maken? De bedoeling is dat hij sowieso die weken 1 tm 53 moeten laten zien, dat is nu niet het geval. Hij pakt alleen nog de rijen waar aantal > 0.
Jawel dat maakt wel uit, ik keek er zelf ook overheen.
ue.datum is namelijk NULL als niet aan de join voorwaarde wordt voldaan.

Dus je moet met een subquery een inline view maken:

...
) w
LEFT JOIN
	(SELECT WEEK(ev.datum) weeknr, YEAR(ev.datum) jaarnr
	FROM events e
	INNER JOIN user_event ev ON e.id = ev.event
  	WHERE ev.datum BETWEEN "2013-01-01" AND "2013-12-31") ue
USING (weeknr)
Hoi Ger,

Het is geven geleden maar het werkt nog steeds niet zoals ik wil. De weken die niks zouden moeten hebben geven tot een 1 weer als resultaat, dat is niet de bedoeling natuurlijk. Ik heb het volgende:


SELECT w.weeknr, COUNT(*) AS aantal
FROM (
SELECT @weeknr := @weeknr +1 weeknr
FROM user, (
SELECT @weeknr :=-1
)uservar
LIMIT 54
)w
LEFT JOIN
    (SELECT WEEK(ue.datum) weeknr, YEAR(ue.datum) jaarnr
    FROM event e
    INNER JOIN user_event ue ON e.id = ue.event
    WHERE ue.datum BETWEEN "2012-01-01" AND "2013-12-31"
    AND e.type = 'kamp'
    AND YEAR(e.start) = 2013) boe
USING (weeknr) 
GROUP BY w.weeknr
ORDER BY w.weeknr 


Kan je me het laatste zetje geven? Ik zie door de bomen het bos niet meer...
Je maakt de vergissing (die wel vaker gemaakt wordt) om COUNT(*) te gebruiken. COUNT(*) telt het aantal records, en je krijgt altijd minimaal 1 record per week. Maar als je nu COUNT(boe.weeknr) gebruikt dan worden alleen de records geteld waarin de kolom boe.weeknr een waarde bevat (dus niet de waardeloze).

Reageren