Ik zit min of meer met een volgorde probleem en ik probeer het hieronder in de code uit te leggen/beschrijven. Ik had gedacht dat ik het nooit zou gaan toe passen 'continue <label>'. Is in PHP het statement GOTO de vervanger of... kun je het syntaxis wat netter oplossen?
<?php
$SQLMainQuery = "SELECT...";
$RSM=($con, $SQLMainQuery)
while (odbc_fetch_array($ResultMainQuery) {
current_main_key_value =
Label_Continue:
if (previous_key_value !== current_main_key_value) {
$SQLSubQuery = "SELECT... FROM VIEW WHERE Subquery_value = Mainquery_value";
$RSS=($con, $SQLSubQuery)
//Doe vullen array met sub query waarden
}
previous_key_value = current_main_key_value;
//Doe vullen array MAIN query gegevens
// Zoals je ziet is de WHERE clause van de sugquery afhankelijk van de Main query "WHERE Subquery_value
// = Mainquery_value"
//
// HET PROBLEEM ZIT HEM IN HET LAATSTE MAIN RECORD, WANT DAN WIL JE NOG KIJKEN OF HET ARRAY NOG
// AANGEVULD MOET WORDEN MET SUB QUERY GEGEVENS. Het punt is dat voor de main query je weet niet wanneer
// het laatste record voor een bepaalde key waarde bereikt is, het aantal is voor een bepaalde key
// waarde van een regel verschillend aantal records voor een bepaalde key value gereturned worden.
// LET OP: wat ik bedoel met het aantal records voor een zekere key waarde zijn de afzonderlijke records
// binnen de main query en is een ander aantal dat het totale aantal records van de main query
// Dus zat ik te denken wat in JAVA bestaat "Continue" dus:
continue Label_Continue; //Voer de subquery uit en kijk of de main recods nog aangevuld moeten worden
// Of is dat het bekende 'basic' syntax "GOTO"
}
?>
Is dit niet gewoon een hele ingewikkelde manier om een LEFT (of RIGHT) JOIN uit te voeren?
EDIT: zoals ik het zie heb je een soort van verzameling A en een verzameling B en in verzameling B zitten meerdere items die bij één item van A horen. Met een query op verzameling A met een LEFT JOIN op B kun je in 1x alle gewenste informatie ophalen. Het uitsplitsen van resultaten in een array kun je on-the-fly te doen door te kijken of het item uit A verandert tijdens elke iteratie.
Nee, dat denk ik niet, al ben ik ook maar een goed willende query programmeur. Maar wat het is in de main query groepeer ik bepaalde zaken op basis van twee velden. Die sub query moet op basis van het groepsniveau weer uitgevoerd worden, die op zich ook weer gegroepeerd is.
Ik heb het inmiddels met GOTO aan het werken, maar het voelt zo verkeerd...
(Het is ook wel geinig als je uitleg van PHP.net er bij naast legt is het precies mijn situatie. Toen ik het vorige week heb opgezet dacht ik Wow, lekker mooi zo kan ik het oplossen, totdat ik zag dat voor het laatste main regel de sub regel er van ontbrak....)
>> Nee, dat denk ik niet, al ben ik ook maar een goed willende query programmeur. Maar wat het is in de main query groepeer ik bepaalde zaken op basis van twee velden. Die sub query moet op basis van het groepsniveau weer uitgevoerd worden, die op zich ook weer gegroepeerd is.
Precies, en dat los je op met joins, en niet in je code.
De mogelijkheden met SQL zijn bijna oneindig. Oplossen met joins, nested selects of subquery's binnen een hoofdquery. Data verzamelen in php zoveel mogelijk of altijd voorkomen. Een 2e query afvuren in een PHP WHILE of FOR loop is killing, steeds opnieuw naar het MySQL engine gaan is echt niet okee. Door gebrek aan diepgaande SQL kennis wordt er vaak mega veel data opgehaald en geprocessed in php array's met als gevolg performance problemen nu of op termijn, memory exhausted problemen etc. Kortom oplossn in SQL en ik denk dat hier nested selects wel kunnen helpen. Ook zorgvuldig (extra) indexen plannen om de MySQL performance te garanderen.
Ok, dan hoop ik dat jullie mij hiermee kunnen helpen door de sqlMain en de sqlSub samen te voegen. Ook met een sub query zie ik het even niet maar ik ben zeker bereid om te leren.
<?php
$sqlMain = "SELECT ISNULL(vra.SEKLVL3 COLLATE SQL_Latin1_General_CP1_CI_AS, 'LEEG') as SEKLVL3
,ISNULL(vra.NORMVALUE COLLATE SQL_Latin1_General_CP1_CI_AS, 'LEEG') as NORMVALUE
,sum(vra.WAARDE + vra.WAARDE2) as VALUE
FROM dmn.view_xxxx vra
WHERE vra.JAAR = ".$year."
AND vra.MAAND = ".$month."
GROUP BY vra.SEKLVL3 COLLATE SQL_Latin1_General_CP1_CI_AS
,vra.NORMVALUE COLLATE SQL_Latin1_General_CP1_CI_AS
ORDER BY (CASE WHEN vra.SEKLVL3 COLLATE SQL_Latin1_General_CP1_CI_AS IS NULL THEN 1 ELSE 0 END),
vra.SEKLVL3 COLLATE SQL_Latin1_General_CP1_CI_AS;";
if (($keyPreviousSectorLvl3 !== $keySekLvl3) && ($keyPreviousSectorLvl3 !== '')) {
// Het beruchte Goto label
Label_CheckSubrows:
$sqlSUB = "SELECT ISNULL(vra.SEKLVL4 COLLATE SQL_Latin1_General_CP1_CI_AS, 'LEEG') as SEKLVL4
,ISNULL(vra.NORMVALUE COLLATE SQL_Latin1_General_CP1_CI_AS, 'LEEG') as NORMVALUE
,sum(vra.WAARDE + vra.WAARDE2) as VALUE
FROM dmn.view_xxxx vra
WHERE vra.SEKLVL3 = '".$keySekLvl3."'
AND vra.JAAR = ".$year."
AND vra.MAAND = ".$month."
GROUP BY vra.SEKLVL4 COLLATE SQL_Latin1_General_CP1_CI_AS
,vra.NORMVALUE COLLATE SQL_Latin1_General_CP1_CI_AS
ORDER BY (CASE WHEN vra.SEKLVL4 COLLATE SQL_Latin1_General_CP1_CI_AS IS NULL THEN 1 ELSE 0 END),
vra.SEKLVL4 COLLATE SQL_Latin1_General_CP1_CI_AS;";
$getResultSub = odbc_exec($con, $sqlSUB);
while($row = odbc_fetch_array($getResultSub)) {
if ($keySubRowSeKLvl4 !== odbc_result($getResultSub, 'SEKLVL4')) {
$keySubRowSeKLvl4 = odbc_result($getResultSub, 'SEKLVL4');
}
}
// Hier verder met de (volgende) main record --> welke een kolom moet zijn
if (laatste main record)
goto Label_CheckSubrows; // voeg nog de laatste subregels toe aan de presentatie
}
}
?>
Beide query's geven de sommatie terug die per kolom getoond moet vorden:
Dus voor SekLvl3 resp. SekLvl4 worden records gereturned, die overeenkomstig in één van de NORMVALUE kolommen getoond moeten worden. Maar niet iedere kolom voor iedere regel is altijd gevuld, dat varieerd. Voor beide query wordt dezelfde view gebruikt
Ik hoop dat ik het duidelijk heb kunnen maken, waar het om gaat en mijns inziens kan dit niet met sub query, maar zoals eerder gezegd ik ben altijd bereid om te leren en mijn kennis uit te breiden.