Autor Zpráva
Sidbin
Profil
Dobrý den,
V současnosti mám tyto dva scripty na vytažení dat z MySQL. Jeden vytáhne data z databáze o půlnoci (ovšem čas prvního záznamu může být v čase 0:00-0:15, což není však tak podstatné), druhý vytáhne současná data (php pak tyto data odečte a zobrazí).
Rád bych vytáhnul i další další půlnoční hodnoty například 14 dní zpět.

$data=mysql_fetch_assoc(mysql_query("SELECT * FROM XXXYYY ORDER BY `index` DESC LIMIT 1"));

$data0=mysql_fetch_assoc(mysql_query("SELECT * FROM XXXYYY WHERE UNIX_TIMESTAMP(`index`) > UNIX_TIMESTAMP( CURDATE() ) ORDER BY `index` LIMIT 1"));

Děkuji za radu.
juriad
Profil
Sidbin:
Chceš tedy historické záznamy, které jsou vždy prvními za daný den.

Tento dotaz by měl vrátit aktuální záznam spolu se záznamy za poslední půlnoci (ten aktuální záznam vrátí dvakrát pokud je roven půlnočnímu - ale to je nejspíš správně, kdyžtak odstraň slovo ALL):
(SELECT x.*
 FROM   XXXYYY AS x
        JOIN (SELECT MIN(`index`) AS pulnoc
              FROM   XXXYYY
              GROUP  BY DATE(`index`)) AS y
          ON x.`index` = y.pulnoc)
UNION ALL
(SELECT *
 FROM   XXXYYY
 ORDER  BY `index` DESC
 LIMIT  1)
ORDER  BY `index` DESC
LIMIT 15  

Mimochodem, proč pojmenováváš sloupec index, když je to rezervované slovo? Takto ten název musíš všude escapovat.
Sidbin
Profil
Zkoušel jsem to v phpadmin a funguje to. zobrazí to tedy aktualní stav, plus zbytek půlnočních hodnot.
U toho výpisu pro jeden řádek mě to bylo jasné, ale u upracování více řádků se raděj zeptám:
Použiji $ plyn = mysql_query (SELECT.....)
$ dnes = mysql_fetch_assoc ($ plyn);
$ vcera = mysql_fetch_assoc ($ plyn);

Bude to tak fungovat?

K tomu indexu, pomohlo by pouhé přejmenování index na něco jiného, nebo by byl potřeba větší zásah?
Databáze vypadá následovně:
index rec_time pak následují čidla a počítadla
2015-03-11 00:00:00 00:00:00 xyz xyz2
Keeehi
Profil
Sidbin:
Bude to tak fungovat?
Bude. Pokud tam ale bude více řádků než dva, tak to bude lepší pouštět cyklem.

pomohlo by pouhé přejmenování index na něco jiného
Ano pomohlo.

A k těm jednotlivým čidlům a počítadlům. Není úplně nejlepší mít čidlo jako jeden sloupec v tabulce. Pokud si seš jistý, že se jejich počet v budoucnu nikdy nezmění, tak ok, ale správný návrh to není. Pokud se ale v budoucnu mouhou počty čidel měnit, pak tu tabulku doporučuji rozdělit na více (2-3).
- tabulka měření: id_měření, čas_začátku, doba
- tabulka čídla: id_čidla, jméno, popis
- tabulka vysledky_měření: id_měření, id_čidla, naměřená_hodnota
Takto to je pak velmi flexibilní. Pokud nejsou potřeba ukládat informace o čidlu samotném (to jméno a popis) dají se pak druhá tabulka s třetí spojit.
Sidbin
Profil
Děkuji za rady.
Čidla mám řazena pořadovým číslem. Pokud tedy změním ten index na něco jiného, jak se změní ten kód pro vytažení dat z mysql?
Zatím mě jde jen o jedno počítadlo s ID s03.
No zkusil jsem pro další zpracování dat tohle a výsledek byl po odečtení nula:

while ($row = mysql_fetch_array($result))
{
try
{

$dnes = mysql_fetch_assoc ($s03);
$vcera = mysql_fetch_assoc ($s03);
}
catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}
mysql_close($con);
echo $output;
}
$dness03 = $dnes - $vcera;

?>
<html>
Dnes:<?php echo $dness03; ?>m3
</html>
juriad
Profil
$aktualni = mysql_fetch_assoc($result);
echo "Aktualne: " . $aktualni['plyn'];
while ($pulnoc = mysql_fetch_assoc($result)) {
  echo "Rozdil oproti " . $result['index'] . " je " . ($aktualni['plyn'] - $pulnoc['plyn']);
}
Kde samozřejmé zvýrazněné názvy musí odpovídat těm, které vrátí dotaz.
mysql_fetch_assoc vrací pole, k jehož prvkům přistupuješ pod názvy sloupečků.
mysql_* funkce budou v budoucnu odstraněny, zvaž přechod na mysqli_* (liší se jen nepatrně).
Kajman
Profil
juriad:
Pro velké množství dat nebude vhodné počítat minima pro všechny dny. Lepší bude omezit hledání jen na těch 14 dní. Pokud bude na sloupci s časem index, bude to svižnější. Tedy to upravit na něco jako...

(SELECT x.*
 FROM   XXXYYY AS x
        JOIN (SELECT MIN(`index`) AS pulnoc
              FROM   XXXYYY
              WHERE  `index`>=subdate('2015-03-11', 14 days)
              GROUP  BY DATE(`index`)) AS y
          ON x.`index` = y.pulnoc)
UNION
(SELECT *
 FROM   XXXYYY
 ORDER  BY `index` DESC
 LIMIT  1)
ORDER  BY `index` DESC 
Sidbin
Profil
juriad:
Pokud jsem ten php jsem pochopil správně jde pouze pro zpracování jednoho dne. Pokud bych chtěl řešit těch 14 dní, musím z toho tvého předchozího scriptu získat proměnné.
Pak bych to už jen řešil stylem získání hodnoty počítadla ze sloupce S03 (protože zbytek není potřeba načítat, jsou to čidla teplot a analogového vstupu).
$spotreba1 = $1 - $2;
$spotreba2 = $2 - $3;
$spotreba3 = $3 - $4;
$spotreba4 = $4 - $5;
....atd. Kde proměnné 1-14 budou načtené z tvého mysql (a čím vyšší číslo, tím starší první záznam dne). Zasekl jsem se totiž na zpracování těch 14 hodnot, pokud chci načíst jen jednu, mám jasno, tak jsem to měl udělané předtím.

Každopádně díky za info o mysqli_ , zkusím se na to podívat, budu muset upravit scripy i pro svoje další dotazy na mysql, které plní tabulky a grafy

Kajman:
Tady bych musel vložit php script, aby se datum v závorce subdate změnilo každý den na aktualní, že?
U tvého návrhu bych měl změnit sloupec `index` s datem s časem na vedlejší, který obashuje pouze čas, chápu to správně? Nemá být `index` jedinečná hodnota?

Děkuji oběma.
juriad
Profil
Sidbin:
Pokud těch dat nejsou statisíce, nemá to smysl moc řešit. Máš teď dotaz, který funguje a kdybys potřeboval zrychlit, poznamenej si odkaz sem.

Pokud jsem ten php jsem pochopil správně jde pouze pro zpracování jednoho dne.
Naopak, ten skript v [#6] vypíše aktuální hodnotu a pak pro každou půlnoc (kterou dotaz vrátil) rozdíl aktuální a tehdejší.
mysql_query vrátí něco (co přesně je nedůležité; důležité je jen to, že s tím přímo nemůžeš pracovat). K další práci slouží funkce mysql_fetch_assoc, kterým předáš výsledek funkce mysql_query a ona ti vrátí první následující řádek. Vrátí jej v podobě asociativního pole, kde klíče jsou shodné jako názvy vybraných sloupečků v dotazu.

Tedy výpis spotřeby za jednotlivé dny by vypadal takto:
$aktualni = mysql_fetch_assoc($result);
$plyn = $aktualni['plyn'];
$datum = $aktualne['index'];

while ($pulnoc = mysql_fetch_assoc($result)) {
  echo 'Od ' . $pulnoc['index'] . ' do ' . $datum . ' se spotřebovalo ' . ($plyn - $pulnoc['plyn']) . ' jednotek plynu';
  $plyn = $pulnoc['plyn'];
  $datum = $pulnoc['index'];
}
Všimni si, že se proměnné $plyn a $datum napřed nastaví na aktuální hodnoty, a pak se přepíšou postupně na hodnoty z jednotlivých půlnocí (všech vrácených dotazem).
Ten průchod všemi řádkami je zajištěn tím while cyklem.
Sidbin
Profil
No právě těch dat je za den 96 (data se nahrávají po 15 minutách). Ty statisíce neřeším (i kdyby to bylo 365 dní dat například do grafu, bude to 35000/24, ale zatím mě zajímá 14 dní, maximálně měsíc).
Zpracuji je dvěma zpusoby. Tam docela chápu jak se zpracovávají ta data, u toho tvého kódu nejsem stále schopný zobrazit výsledek. Pozděj bych ta data z denní spotřeby plynu hodil do grafu, zatím se je chci snažit narvat do tabulky.

1)Vytáhnu aktualní řádek a zobrazím teploty z proměnných.
$data=mysql_fetch_assoc(mysql_query("SELECT * FROM XXXYYY ORDER BY `index` DESC LIMIT 1"));
$time = $data["rec_time"];
$temp02 = $data["temp02"]; //topna voda
$temp03 = $data["temp03"]; /vratna voda

2)Vytáhnu 100-3000 řádků (den - 31 dní +-) 10 čidel.
Zpracuji do Json a ve Flotu vytvořím graf.

$result = mysql_query("SELECT * FROM XXXYYY ORDER BY `index` DESC LIMIT " . $num);
while ($row = mysql_fetch_array($result))
{
try
{
$temp_array["Datetime"] = strtotime($row["index"]." UTC")*1000;
$temp_array["temp01"] = $row["temp01"];
$temp_array["temp02"] = $row["temp02"];
$return[] = $temp_array;
}
catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}
$output = json_encode($return);
Sidbin
Profil
omlouvám se za další příspěvek bez editace.

No stále zkouším tuto kombinaci a nedaří se mě zobrazit ani například jednu z proměných.
Vypisuje to aktuálně chybu na řádku : echo 'Od ' . $pulnoc['index'] . ' do ' . $datum . ' se spotřebovalo ' . ($plyn - $pulnoc['s03']) . ' m3';

<?php
$con = mysql_connect("xxxx","XXXYYY","123");

if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }
else
{
 mysql_select_db("XXXYYY", $con);

$result = mysql_query (SELECT x.*
 FROM   XXXYYY AS x
        JOIN (SELECT MIN(`index`) AS pulnoc
              FROM   XXXYYY
              WHERE  `index`>=subdate('2015-03-11', 14 days)
              GROUP  BY DATE(`index`)) AS y
          ON x.`index` = y.pulnoc)
UNION
(SELECT *
 FROM   XXXYYY
 ORDER  BY `index` DESC
 LIMIT  1)
ORDER  BY `index` DESC 

$aktualni = mysql_fetch_assoc($result);
$plyn = $aktualni['s03'];
$datum = $aktualne['index'];

while ($pulnoc = mysql_fetch_assoc($result)) {
  echo 'Od ' . $pulnoc['index'] . ' do ' . $datum . ' se spotřebovalo ' . ($plyn - $pulnoc['s03']) . ' m3';
  $plyn = $pulnoc['s03'];
  $datum = $pulnoc['index'];
}
?>
juriad
Profil
Máš tam chyby:
ten dotaz musí být v uvozovkách (řádky 12 - 24)
není ukončené volání funkce mysql_query (řádek 24)
překlep (aktualne -> aktualni) (řádek 28)

Jakou chybu to vypisuje?
Sidbin
Profil
opraveno na:
12: $result = mysql_query ("SELECT x.*
24: ORDER BY `index` DESC");
28: $datum = $aktualni['index'];
když přidám výpis proměnné aktualní, hodí to zase chybu
<html>
test: <?php echo $aktualni; ?>
</html>

Což vyhodí chybu na řádku 38, což je </html>
juriad
Profil
Jakou chybu?

Chybí ti tam ještě ukončení else, které začalo na 9. řádku. Někam na konec přidej zavírací složenou závorku.
Sidbin
Profil
No na uplný konec php jsem dal závorku a už to nevypisuje chybu.
když dám tento pokus o nějaké vypsání proměnných, tak to nevypíše nic, jen text: test: a čárku
<html>
test: <?php echo $plyn; ?>, <?php echo $datum; ?>
</html>

Chtěl jsem ty data zpravovat do tabulky, pozděj získávat JSON i pro zobrazení grafu skrze FLOT. Například teploty mě fungují OK, graf spotřeby plynu (ale pouze rostoucí celková spotřeba) taky funguje. Tady nejsem schopný získat výpis těch hodnot.
Sidbin
Profil
Ahoj, ještě se vracím k tomuto tématu. Mám již ten kód funkční, ale rád bych to dostal teda do grafu. Používám pro grafy FLOT.
Potřeboval bych z toho výpisu výpočtených hodnot udělat JSON. díky.
$solar = $aktualni['s02'];
$datum = $aktualni['index'];
 
while ($pulnoc = mysql_fetch_assoc($result)) {
  echo $pulnoc['index'] ." , ". (Round(($solar - $pulnoc['s02']),3)) . "<br>\n"; 
  $solar = $pulnoc['s02'];
  $datum = $pulnoc['index'];
}
pro teploty používám tohle (flot.php):
while ($row = mysql_fetch_array($result))
{
    try
    {
        $temp_array["Datetime"] = strtotime($row["index"]." UTC")*1000;
        $temp_array["temp10"] = $row["temp10"];        //kuchyn dole
        $return[] = $temp_array;
    }
    catch (Exception $e) {
        echo 'Caught exception: ',  $e->getMessage(), "\n";
    }
}
$output = json_encode($return);
plus tohle vytáhne data pomocí flot.php a zpracuje se to do grafu
    function initGraphs(number){
    $.get("/flot.php",{num:number}, function (data) {
            var data2 = eval( data );
            var temps06 = [];
            
            for (var i=0; i<data2.length; i++)
            {
                 temps06.push([data2[i].Datetime, data2[i].temp06]);
                 
            }
            $.plot($("#Solar"), [{label: "Solár", data:temps06}], {series: {lines: {show: true}, color: "red"}, xaxis: {mode: "time"}});
            
        });
Kajman
Profil
Tak to udělejte stejně, jak u teplot. Nebo s čím konkrétním máte problém?
Sidbin
Profil
Asi je někde chyba v předávání dat, u teplot to tahám přímo z DB bez zpracování (rozdílu přírustku spotřeby za den a vytažení posledních 31 dnů).
Na konci toho prvního kódu mám:
$output = json_encode($return);
A stránka z grafem ji volá:
    function initGraphs(number){
    $.get("/solsp.php", function (data) {
            var data2 = eval( data );
            var s02 = [];
            
            for (var i=0; i<data2.length; i++)
            {
                 s02.push([data2[i].Datetime, data2[i].s02]);
      }
            $.plot($("#Solar"), [{label: "Solár", data:s02}], {series: {lines: {show: true}, color: "red"}, xaxis: {mode: "time"}});
            });
      }

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0