Hoe krijg ik max waarde en tijdstip van afgelopen 24uur?

Status
Niet open voor verdere reacties.

Tijger81

Gebruiker
Lid geworden
2 jan 2010
Berichten
397
Ik heb een database met de kolommen time en value:

time value
2020-02-02 12:00 26
2020-02-02 13:00 24

Dit is mijn query in PHP:
PHP:
$data = pg_query($conn, "SELECT to_char(date_trunc('hour', time),'YYYY-MM-DD HH24:MI') AS tijd, max(value) AS max_waarde FROM lokatie GROUP BY tijd ORDER BY tijd DESC Limit 24");	

if ($data) {
    $arrData3 = array();
    $arrData4 = array();         
    while($row3 = pg_fetch_array($data)) {
        array_push($arrData3, array(
            $row3["max_waarde"]
        ));           
        array_push($arrData4, array(
            $row3["tijd"]
        ));
    }
}

$jsonEncodedData3= json_encode($arrData3);
$returnvalue['max'] = $jsonEncodedData3;
$jsonEncodedData4= json_encode($arrData4);
$returnvalue['maxtijd'] = $jsonEncodedData4;

En dan haal ik max en maxtijd op met een Ajax call in javascript.

Het probleem is dat ik 24 x de max waarden krijg van elk uur van de afgelopen 24 uur.
Maar ik heb alleen de hoogste waarde en de tijd ervan nodig van de afgelopen 24uur.

Wie kan mij helpen hierbij?

Mvg
 
Laatst bewerkt door een moderator:
Is er een bepaalde reden dat je "1 waarde als array" in een array pusht.
Code:
array_push($arrData3, array(
    $row3["max_waarde"]
));

Kan het niet gewoon zo om beide waardes in de array's te pushen?
Code:
$arrData3[] = $row3["max_waarde"];
$arrData4[] = $row3["tijd"];
 
Ik dacht dat ik anders de 2 uitkomsten niet apart kon opnemen met de Ajax call. Maar dat kan dus wel?
Ik ben een beginneling met PHP en heb al het gevoel dat mijn query omslachtig is. Kun je mij op weg helpen om de max van de laatste 24 uur te krijgen?
 
De json response in JS van een ajax call is een string met object notatie. In dit object kunnen andere objecten en arrays zitten (in JS is een array eigenlijk een eenvoudig object, zie "typeof"). Ook kunnen er geneste arrays in een json zitten.

In de json string zou het 1 array kunnen zijn (behalve als row3 bij een cel van een andere array hoort; idem voor row4). Bekijk de array in json voorbeelden (klik).
Code:
{
"....": "....",
"row3": ["....", "....", "...."],
"row4": ["....", "....", "...."]
}

Het lijkt erop dat je to_char (Oracle SQL) en date_trunc (PostgreSQL) in MySql gebruikt.
Ik ben niet echt thuis in (my)sql maar miscchien kan je hiermee verder
Code:
SELECT
  DATE_FORMAT(time, '%Y-%m-%d %H:00') AS tijd,
  MAX(value) AS max_waarde
FROM lokatie
GROUP BY tijd
ORDER BY tijd DESC
LIMIT 24

Mooier is misschien een WHERE waarin je de laatste 24 uur opvraagt (ipv LIMIT).
 
Laatst bewerkt:
Ik ga die json voorbeelden proberen te gebruiken.
Wij hebben een postgres database. Kun je Date_format ook daarbij gebruiken? Je hebt MySQL, postgres,enz.. kun je daar dezelfde functies bij gebruiken eigenlijk?
 
Je hebt MySQL, postgres,enz.. kun je daar dezelfde functies bij gebruiken eigenlijk?
In PG SQL mag je de functies date_trunc() en to_char() idd gebruiken. Bij voorbeelden op internet altijd even kijken of een functie gebruikt mag worden :)

Ik ben niet echt thuis in sql, het wordt dus veel googelen en trial & error.
 
Ik ben sowieso geen ster erin en de sql die in de buurt komt en op internet zie wordt ik duizelig van. .Maar ik heb gegoogled en het lukt me om de max per uur van 24 uur te krijgen. Ik krijg dan 24 waarden met de tijd erbij. Misschien is het mogelijk om van de 24 waarden in JavaScript de hoogste te krijgen en dan de tijd die erbij hoort. Iets van Math.max() heb ik geprobeerd maar nog zonder succes. Dus dat JavaScript uitzoekt welke van de 24 de hoogste is.
 
Je kan in Javascript (in de browser) niet rechtstreeks records lezen in de database (op de server). Dit kan eventueel met ajax maar daarvoor moet een stukje javascript én php worden geschreven. Over je vraag of het in Javascript mogelijk is.
Code:
<div id="result"></div>

<script>
var data, i, maxValue = 0, arrRows = [], txt = '';

// voorbeeld: 78 komt 2x voor als hoogste waarde in ongesorteerde records.
data = [
    ["2020-01-28 10:00", 26],
    ["2020-01-28 20:00", 78],
    ["2020-01-28 16:00", 44],
    ["2020-01-28 21:00", 64],
    ["2020-01-28 14:00", 12],
    ["2020-01-28 13:00", 78],
    ["2020-01-28 23:00", 53],
    ["2020-01-28 19:00", 39]
];

// wat is de hoogste waarde?
for (i = 0; i < data.length; i++) {
    maxValue = Math.max(maxValue, data[i][1]);
}

// verzamel de rijen met de hoogste hierboven gevonden waarde in een array.
for (i = 0; i < data.length; i++) {
    if (data[i][1] == maxValue) {
        arrRows.push(data[i]);
    }
}

// sorteer eventueel op eerste kolom (sortFunction komt van MDN).
arrRows.sort(sortFunction);
function sortFunction(a, b) {
    if (a[0] === b[0]) return 0;
    else if (a[0] < b[0]) return -1; else return 1;
}

// toon de rijen in <div id="result"></div>
for (i = 0; i < arrRows.length; i++) {
    txt =  txt + arrRows[i][0] + " : " + arrRows[i][1] + "<br>";
}
document.querySelector('#result').innerHTML = txt;
</script>
 
Laatst bewerkt:
arrRows[0] + " : " + arrRows[1]

arrRows[0] is max waarde en arrRows[1] is de tijd?
 
arrRows[0] is max waarde en arrRows[1] is de tijd?

Yep, maar dan omgekeerd.
In de for loop is de rij, [0] is kolom datum/tijd, en [1] is kolom waarde.

Ik ben er vanuit gegaan dat het volgende kan voorkomen:
datum/tijd kan ongesoreerd in de array staan -> wordt gesorteerd met sortFunction
een max. waarde kan meerdere keren voorkomen (in mijn voorbeeld 78) -> wordt bijgehouden in array arrRows

De sortFunction sorteert de rijen op datum/tijd.
 
Laatst bewerkt:
Maar de datum tijd pakt hij toch uit de rij waar de max value voorkomt. Dan hoeft de tijd toch niet gesorteerd te worden.
 
Stel dat 78 de hoogste waarde is en dat deze waarde in 8 rijen voorkomt, dan is het netjes dat de gevonden rijen gesorteerd op het scherm worden getoond. Als de sql query de ORDER BY tijd heeft dan kan je in Javascript de sorteer regels eruit halen.

Uitleg script #8
(met records bedoel ik hier de array's in het data array)

Eerst door alle records om te kijken wat de maximale waarde "maxValue" is, verder niets.
Dan nogmaals door alle records en elk record met "maxValue" in een array "arrRows" zetten.
In array "arrRows" staan dan één of meerdere record(s) met de gevonden maximale waarde.
Eventueel array "arrRows" sorteren maar dit kan handiger in de sql query.
Als laatste de record(s) uit array "arrRows" op het scherm tonen.

Als je het script #8 in een testbestandje zet dan kan je met console.log() zien wat er overal gebeurt.

Opmerking: het script kan veel compacter door mapping te gebruiken maar nu is het wat makkelijker leesbaar denk ik.
 
Laatst bewerkt:
Je hebt gelijk. Er kunnen uren zijn met dezelfde temp waarden. Ik wilde eerst per minuut doen,maar dan is die kans nog groter en de temp wordt om 15min gemeten dus dat kan sowieso niet.

De order by tijd zit al in de PHP query trouwens
 
In deze javascript code maakt het eigenlijk niet uit wat de intervaltijd is want elke rij die de hoogste waarde bevat wordt getoond. Hoe korter de intervaltijd, des te meer kans op meer regels met dezelfde waarde :)
 
Niet getest maar misschien kan je het gebruiken als ideetje voor de json.
PHP:
$jsonArray = [];
$status = 'ok';
$conn = pg_pconnect("dbname=publisher");
if (!$conn) {
    $status = 'error_pg_pconnect';
} else {
    $sql = "SELECT ........";
    $result = pg_query($conn, $sql);
    if (!$result) {
        $status = 'error_pg_query';
    } else {
        while ($row = pg_fetch_row($result)) {
            $jsonArray[$row[0]] = $row[1];
        }
        if (empty($jsonArray)) {
            $status = 'no_records';
        }
    }
}
$jsonArray["status"] = $status;
echo json_encode($jsonArray);
 
Code:
[["529","2020-02-03 09"],["391","2020-02-03 08"],["384","2020-01-31 22"],["375","2020-01-31 21"],["392","2020-01-31 20"],["383","2020-01-31 19"],["389","2020-01-31 18"],["403","2020-01-31 17"],["399","2020-01-31 16"],["415","2020-01-31 14"],["402","2020-01-31 13"],["437","2020-01-31 12"],["423","2020-01-31 11"],["422","2020-01-31 10"],["404","2020-01-31 09"],["378","2020-01-31 08"],["441","2020-01-30 15"],["501","2020-01-30 14"],["580","2020-01-30 13"],["682","2020-01-30 12"],["500","2020-01-30 11"],["432","2020-01-30 10"],["400","2020-01-30 09"],["401","2020-01-30 08"]]

Het lukt nog niet. Na JSON(parse)) komen mijn waarden eruit als bovenstaand. De MaxValue komt eruit als NAN
 
Als ik het resultaat een format geef, dan ziet het er goed uit.
In het array zitten sub-arrays met elk een combinatie van "max_waarde" en "datum_met_ur"
Code:
[
   ["529","2020-02-03 09"],
   ["391","2020-02-03 08"],
   ["384","2020-01-31 22"],
   ["375","2020-01-31 21"],
   ...
   ["404","2020-01-31 09"],
   ["378","2020-01-31 08"],
   ["441","2020-01-30 15"],
   ["501","2020-01-30 14"],
   ...
   ["400","2020-01-30 09"],
   ["401","2020-01-30 08"]
]

Echter door de gekozen SELECT worden meerdere datums gegeven.
De SELECT zou aangepast moeten worden voor een output van 24 uur (misschien met WHERE).
Optioneel kan het tijdformat '%Y-%m-%d %H:%m' zijn als de waardes meerdere keren per uur voorkomen.

Voorbeeld JS (niet getest)
Code:
var response = [["529","2020-02-03 09"],["391","2020-02-03 08"],["384","2020-01-31 22"], ... ["401","2020-01-30 08"]];
for (var i = 0; i < response.length; i++) {
   console.log( 'Max waarde  : ' + response[i][0] );
   console.log( 'Datum / uur : ' + response[i][1] );
}
 
Hoi,

Het is nu wel gelukt. Ik krijg de hoogste waarde. In PHP had ik de tijd en waarde verkeerd om staan.
Maar ik krijg wel 3x het resultaat in #result
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan