Autor Zpráva
jtfcobra
Profil
Ahoj chtel bych nechat pocitat mysql ale nevim jak na to ... poradite?


Puvodni pocitani PHP:
  <?php
require_once('Connections/mereni.php');
$db = mysql_connect($hostname_test, $username_test, $password_test);
mysql_select_db($database_test,$db);
$vysledek = mysql_query($result); 



$hledat=  "V9";
$hledat2= $_GET["rok"]."-". $_GET["mesic"]."-";
$vysledek = mysql_query($result); // proveden&iacute; sql dotazu 
if(!$data=mysql_query("SELECT SPOTREBA FROM spotreba WHERE `MERAK`='".$hledat."'  AND `DATUM` LIKE '%".$hledat2."%'  ",$db)) 
    {echo "<h2>Nepodařilo se připojit k tabulce zbozi.</h2>\n"; break;}
while ($zaznam = mysql_fetch_array($data)){
$celkem1=$celkem1+round(str_replace(",", ".",$zaznam["SPOTREBA"]),2);
$celkemKC1=$celkem1*$cena1;
};
echo round($celkem1,2).'</br><div align="right">('.$pl.')</div>';
?>


Zkousím pocitani Mysql:
  <?php
$hledat=  "V9";
$hledat2= $_GET["rok"]."-". $_GET["mesic"]."-";
$celkem1='0';
$vysledek = mysql_query($result); // proveden&iacute; sql dotazu 
if(!$data=mysql_query("SELECT '".$celkem1."'+SPOTREBA FROM spotreba WHERE `MERAK`='".$hledat."'  AND `DATUM` LIKE '%".$hledat2."%'  ",$db)) 
    {echo "<h2>Nepodařilo se připojit k tabulce zbozi.</h2>\n"; break;}
while ($zaznam = mysql_fetch_array($data)){
$celkemKC1=$celkem1*$cena1;
};
echo round($celkem1,2).'</br><div align="right">('.$pl.')</div>';
?>
Keeehi
Profil
"SELECT sum(`SPOTREBA`) AS celkem FROM `spotreba` WHERE `MERAK`='".$hledat."'  AND `DATUM` LIKE '%".$hledat2."%'"

Pár poznámek
- pokud ti to běží doma a nikdo se k tomu nemůže dostat, tak ok, ovšem pokud to máš někde veřejně, tak neošetřuješ vstupní proměnné => někdo ti to může "hacknout"
- datum měj v databázi ve sloupci typu date. Pak se můžeš ptát na mnohem zajímavější statistiky. Ty můžeš teď zobrazovat spotřebu jen v určité měsíce, co by se dalo je zobrazování spotřeby třeba za posledních třicet dní, zjišťování průměrné spotřeby přes týden oproti spotřebě přes víkend a mnoho dalšího co s LIKE se zvládnout nedá.
jtfcobra
Profil
Jak myslis ošetřit proti háčků, jak bych mohl jinak hledat měsíc a den nebo týden atd?
jtfcobra
Profil
Udělal jsem to takle a nefunguje to

Spotřeba je uložená v typu: text (0.0) jestli v tom neni problem?

<?php
// Spojeni
require_once('Connections/mereni.php');
$db = mysql_connect($hostname_test, $username_test, $password_test);
mysql_select_db($database_test,$db);
$vysledek = mysql_query($result); 

// Pocitani PHP
$hledat=  "V9";
$hledat2= $_GET["rok"]."-". $_GET["mesic"]."-";
$vysledek = mysql_query($result); // proveden&iacute; sql dotazu 
if(!$data=mysql_query("SELECT SPOTREBA FROM spotreba WHERE `MERAK`='".$hledat."'  AND `DATUM` LIKE '%".$hledat2."%'  ",$db)) 
    {echo "<h2>Nepodařilo se připojit k tabulce zbozi.</h2>\n"; break;}
while ($zaznam = mysql_fetch_array($data)){
$celkem1=$celkem1+round(str_replace(",", ".",$zaznam["SPOTREBA"]),2);
};
echo 'Pocitani PHP: '.round($celkem1,2);


// Pocitani mysql
$hledat=  "V9";
$hledat2= $_GET["rok"]."-". $_GET["mesic"]."-";
$celkem1='0';
$vysledek = mysql_query($result);
if(!$data=mysql_query("SELECT sum(`SPOTREBA`) FROM spotreba WHERE `MERAK`='".$hledat."'  AND `DATUM` LIKE '%".$hledat2."%'  ",$db)) 
    {echo "<h2>Nepodařilo se připojit k tabulce zbozi.</h2>\n"; break;}
while ($zaznam = mysql_fetch_array($data)){
$celkem1=round(str_replace(",", ".",$zaznam["SPOTREBA"]),2);
};
echo 'Pocitani Mysql: '.round($celkem1,2);
?>
mimochodec
Profil
jtfcobra:
Spotřeba je uložená v typu: text (0.0) jestli v tom neni problem?

Je to problém. Proč to děláš?
Taps
Profil
Jtfcobra
Pro desetinna cisla je mozne v databazi pouzit datovy typ double nebo float
mimochodec
Profil
jtfcobra:
Pro datum používej datový typ DATE, pro čísla používej číselné typy. Jestli znáš počet desetinných a celých míst, použil bych DECIMAL.
Filtr pro datum bude vypadat takto.
... WHERE YEAR(DATUM)=".$_GET["rok"]." AND MONTH(DATUM)=".$_GET["mesic"]

Obecně: nevhodně zvolený datový typ může znamenat, že ti aplikace nefunguje, nebo funguje, ale musíš kolem toho udělat spoustu práce navíc, nebo se to s přibývajícími daty zpomaluje až k nepoužitelnosti. Při miliónu řádků už by sis na LIKE znatelně počkal.


Ještě vidím: $celkem1='0';
Mě tohle tak nějak rozčiluje. '0' je text, 0 je číslo. Chceš tady počítat nějaké sumy. Co tě vede k tomu, že použiješ '0'?
Taky nerozumím tomu dvojímu zaokrouhlení. V tom prvním bloku si tam tím prvním round zanášíš docela významnou chybu, v obou těch blocích máš round dvakrát po sobě, stačil by jednou.
juriad
Profil
mimochodec:
To si počkáš i na ten YEAR a MONTH. Pokud chceš použít indexy, musíš použít obyčejné porovnání.
$thisMonth = $rok . '-' . $mesic . '-01';
$nextMonth = ($rok + floor($mesic/12)) . '-'. ($mesic % 12 + 1) . '-01';

SELECT [...] WHERE datum >= $thisMonth AND datum < $nextMonth
jtfcobra
Profil
Ted když mám spotřebu v textu je možné to převést na ten decimal?


Chtěl bych to udělat co nejrozumneji vím že v tom mám bordel


Tak jsem to upravil ale stale nefunguje Pocitani mysql testovaci


<?php
// Spojeni
require_once('Connections/mereni.php');
$db = mysql_connect($hostname_test, $username_test, $password_test);
mysql_select_db($database_test,$db);
$vysledek = mysql_query($result); 
$merak=  "V9";
$rok=$_GET["rok"];
$mesic=$_GET["mesic"];
if ($rok=='13') {$rok=2013;};
if ($rok=='14') {$rok=2014;};
if ($rok=='15') {$rok=2015;};
if ($rok=='16') {$rok=2016;};
if ($rok=='17') {$rok=2017;};
if ($rok=='18') {$rok=2018;};

// Pocitani PHP testovaci
$vysledek = mysql_query($result); // proveden&iacute; sql dotazu 
if(!$data=mysql_query("SELECT SPOTREBA FROM spotreba WHERE YEAR(DATUM)='".$rok."' AND MONTH(DATUM)='".$mesic."' AND MERAK='".$merak."' ",$db)) 
    {echo "<h2>Nepodařilo se připojit k tabulce zbozi.</h2>\n"; break;}
while ($zaznam = mysql_fetch_array($data)){
$celkem1=$celkem1+str_replace(",", ".",$zaznam["SPOTREBA"]);
};
echo 'Pocitani PHP: '.round($celkem1,2).'</br>';


// Pocitani mysql testovaci
$vysledek = mysql_query($result);
if(!$data=mysql_query("SELECT SUM(SPOTREBA) FROM spotreba WHERE `MERAK`='".$merak."'  AND YEAR(DATUM)='".$rok."' AND MONTH(DATUM)='".$mesic."'  ",$db)) 
    {echo "<h2>Nepodařilo se připojit k tabulce zbozi.</h2>\n"; break;}

while ($zaznam = mysql_fetch_array($data)){
$celkem2=str_replace(",", ".",$zaznam["SPOTREBA"]);
};
echo 'Pocitani Mysql: '.round($celkem2,2).'</br>';
?>
RastyAmateur
Profil
Trochu off-topic:
Ještě bych rád zareagoval na tvou funkci mysql_connect(). Včera jsme to řešili v jiném vlákně. Funkce mysql_* již jsou označeny jako zastaralé. Být tebou, přečtu si Fisirův článek a vše opravím, dokud je na to ještě čas...
jtfcobra
Profil
A jak mam udelat podle noveho co je aktualni to spojeni a vypis?
RastyAmateur
Profil
A ještě bych ti rád maličko upravil kód. Máš tam 5 podmínek.

$rok=$_GET["rok"];
if ($rok=='13') {$rok=2013;};
if ($rok=='14') {$rok=2014;};
if ($rok=='15') {$rok=2015;};
if ($rok=='16') {$rok=2016;};
if ($rok=='17') {$rok=2017;};
if ($rok=='18') {$rok=2018;};

Můžeš to upravit na jeden řádek:

$rok = "20".$_GET["rok"];
jtfcobra
Profil
Tohle jo $rok = "20".$_GET["rok"]; ale co kdyz bude prijde rok ve formatu 20xx?
RastyAmateur
Profil
jtfcobra:
Jde o to, že pokud pak změníš / aktualizuješ server na verzi s PHP 7.0 tak ti funkce mysql_connect() (celkově funkce mysql_*) nebude fungovat. Nic měnit nemusíš, ale chtěl jsem tě jen varovat. Pokud nerozumíš tomu Fisirově článku, tak to asi zrovna teď řešit nemusíš... Zase tak urgentní to není :-)


jtfcobra:
Podle těch podmínek jsem usoudil, že v té proměnné $_GET["rok"] máš pouze roky ve zkratce... Pokud tam máš občas "18" a jindy "2018" tak je tvé řešení samozřejmě správné!
mimochodec
Profil
juriad:
Já jsem chtěl doporučit přidání sloupce mesicrok, kde by se ukládalo 12*rok + mesic, ale to už je otázka, jak často by se to používalo. Máš asi pravdu, že datumové funkce nad celým sloupcem nejsou ideál, přesto jsou určitě rychlejší než LIKE.
jtfcobra
Profil
A jak to vidíte s tím výpisem v PHP to přepočítata a MySQL nepočítá
mimochodec
Profil
jtfcobra:
SELECT SUM(SPOTREBA) AS celkova FROM spotreba ...
..
$celkem2=str_replace(",", ".",$zaznam["celkova"]);
jtfcobra
Profil
Děkuji takle to funguje

A slo by ten prikaz zmensit ....? musi tam byt while atd...?

$vysledek = mysql_query($result);
if(!$data=mysql_query("SELECT SUM(SPOTREBA) AS celkova FROM spotreba WHERE `MERAK`='".$merak."'  AND YEAR(DATUM)='".$rok."' AND MONTH(DATUM)='".$mesic."'  ",$db)) 
    {echo "<h2>Nepodařilo se připojit k tabulce zbozi.</h2>\n"; break;}
while ($zaznam = mysql_fetch_array($data)){
$celkem2=str_replace(",", ".",$zaznam["celkova"]);
};
echo 'Pocitani Mysql: '.round($celkem2,2).'</br>';
mimochodec
Profil
jtfcobra:
A slo by ten prikaz zmensit ....?

Když tam zabuduješ #8, bude ten dotaz kratší. Ale zase tam bude o dva řádky víc. Parametr $db je při použití mysql_query nepovinný, break mi tady připadá docela nadbytečný. Taky ty apostrofy uvnitř dotazu, na které se taky vztahuje to, co jsem psal v #7.
jtfcobra
Profil
Udelal jsem test a vysledek


Pocitani PHP: 37290.17
Vyuzita pamet: 0.2416MB (Realne: 0.25MB, Maximalne: 0.2435MB) za 0.00478 sekund

Pocitani Mysql: 37290.17
Vyuzita pamet: 0.2418MB (Realne: 0.25MB, Maximalne: 0.2442MB) za 0.00336 sekund


Finalni kod slo by to jeste lepe optimalizovat?

<?php
// Spojeni
require_once('Connections/mereni.php');
$db = mysql_connect($hostname_test, $username_test, $password_test);
mysql_select_db($database_test,$db);
$vysledek = mysql_query($result); 
$merak=  "V9";
$rok=$_GET["rok"];
$mesic=$_GET["mesic"];
if ($rok=='13') {$rok=2013;};
if ($rok=='14') {$rok=2014;};
if ($rok=='15') {$rok=2015;};
if ($rok=='16') {$rok=2016;};
if ($rok=='17') {$rok=2017;};
if ($rok=='18') {$rok=2018;};

// Pocitani PHP testovaci
$start=microtime(true);
$vysledek = mysql_query($result); // proveden&iacute; sql dotazu 
if(!$data=mysql_query("SELECT SPOTREBA FROM spotreba WHERE YEAR(DATUM)='".$rok."' AND MONTH(DATUM)='".$mesic."' AND MERAK='".$merak."' ",$db)) 
    {echo "<h2>Nepodařilo se připojit k tabulce zbozi.</h2>\n"; break;}
while ($zaznam = mysql_fetch_array($data)){
$celkem1=$celkem1+str_replace(",", ".",$zaznam["SPOTREBA"]);
};
echo 'Pocitani PHP: '.round($celkem1,2).'</br>Vyuzita pamet: ' .round((memory_get_usage()/1024/1024),4) . 'MB ' . '(Realne: ' . memory_get_usage(true)/1024/1024 . 'MB, Maximalne: ' . round(memory_get_peak_usage()/1024/1024,4) .'MB) za ' . round(microtime(true)-$start,5) . ' sekund'.'</br></br>';


// Pocitani mysql testovaci
$start=microtime(true);
$vysledek = mysql_query($result);
$data=mysql_query("SELECT SUM(SPOTREBA) AS celkova FROM spotreba WHERE `MERAK`='".$merak."'  AND YEAR(DATUM)='".$rok."' AND MONTH(DATUM)='".$mesic."'  ",$db); 
while ($zaznam = mysql_fetch_array($data)){
$celkem2=str_replace(",", ".",$zaznam["celkova"]);
};
echo 'Pocitani Mysql: '.round($celkem2,2).'</br>Vyuzita pamet: ' .round((memory_get_usage()/1024/1024),4) . 'MB ' . '(Realne: ' . memory_get_usage(true)/1024/1024 . 'MB, Maximalne: ' . round(memory_get_peak_usage()/1024/1024,4) .'MB) za ' . round(microtime(true)-$start,5) . ' sekund'.'</br>';
?>



Slo by tu udelat neco jako je v Delphi funcke

napriklad
funkcion Nacist(merak,rok,mesic);
(
$vysledek = mysql_query($result);
$data=mysql_query("SELECT SUM(SPOTREBA) AS celkova FROM spotreba WHERE `MERAK`='".merak."'  AND YEAR(DATUM)='".rok."' AND MONTH(DATUM)='".mesic."'  ",$db); 
while ($zaznam = mysql_fetch_array($data)){
$celkem2=str_replace(",", ".",$zaznam["celkova"]);
};
)

A pak bych to pouzil v PHP jako.

napriklad
Nacist(V9,2015,12);

a vratilo by to vysledek?
Taps
Profil
jtfcobra:
ano, šlo. Pokud má být výsledkem pouze jeden řádek hodnot, tak je zbytečné používat cyklus while
<?
function Nacist($merak, $rok, $mesic){

$vysledek = mysql_query($result);
$data = mysql_query("SELECT SUM(SPOTREBA) AS celkova FROM spotreba WHERE `MERAK`='".$merak."'  AND YEAR(DATUM)='".$rok."' AND MONTH(DATUM)='".$mesic."'  ",$db); 
$zaznam = mysql_fetch_array($data);
$celkem2 = str_replace(",", ".", $zaznam["celkova"]);
return $celkem2;
}
?>
Lonanek
Profil
napriklad
Nacist(V9,2015,12);
a vratilo by to vysledek?

Vytvoření funkce zpřehlední kód. RETURNem vrátíte výsledek funkce.
function Vysledek ($merak = "", $rok = 0, $mesic = 0)
{
  $dotaz = "....";
  $result = mysqli_query ($dotaz);
  ...
  ...
  return $celkem2;
}
$vysledek = Nacist("V9", 2015, 12);
Kolik záznamů vrací dotaz? Podle zápisu tipuji, že vždy pouze jeden, pak je zbytečné cyklicky načítat data (while smyčka).

Co se týče ošetření roku, spíše se přikláním k řešení RastyAmateur. Není příliš vhodné dávat uživateli na výběr tolik možných variant zápisu.
řešením je např.:

if ($rok < 100)
{
  $rok = "20". $rok;  // vysledek je text
  $rok = 2000 + $rok;  // vysledek je cislo
}
Vyberte si jednu z variant co má být výsledkem, zda text, nebo číslo.

Taps mne předběhl, jen bych doporučil nastavovat funkcím implicitní hodnoty. Nedojde tak k chybě, pokud se zapomene volat funkce s parametry.
jtfcobra
Profil
Kdyz to mam takle tak to nefunguje
<?
$hostname_test = "....";
$database_test = "....";
$username_test = ".....";
$password_test = "......";
$db = mysql_connect($hostname_test, $username_test, $password_test);
mysql_select_db($database_test,$db);

function AktualniMesicSoucet($merak)
{
$rok=$_GET["rok"];
$mesic=$_GET["mesic"];
if ($rok=='13') {$rok=2013;};
if ($rok=='14') {$rok=2014;};
if ($rok=='15') {$rok=2015;};
if ($rok=='16') {$rok=2016;};
if ($rok=='17') {$rok=2017;};
if ($rok=='18') {$rok=2018;};
$vysledek = mysql_query($result);
$data = mysql_query("SELECT SUM(SPOTREBA) AS celkova FROM spotreba WHERE `MERAK`='".$merak."'  AND YEAR(DATUM)='".$rok."' AND MONTH(DATUM)='".$mesic."'  ",$db); 
$zaznam = mysql_fetch_array($data);
$pren = str_replace(",", ".", $zaznam["celkova"]);
return $pren;
}
?>

pise chybu
Warning: mysql_query() expects parameter 2 to be resource, null given in /data/web/virtuals/73581/virtual/www/spotreba_kompletni_prehled3.php on line 87

Warning: mysql_fetch_array() expects parameter 1 to be resource, null given in /data/web/virtuals/73581/virtual/www/spotreba_kompletni_prehled3.php on line 88
0
(0)



a kdyz to mam takle napsane tak je to OK ale asi to dela vice spojeni
 <?
function AktualniMesicSoucet($merak)
{
$rok=$_GET["rok"];
$mesic=$_GET["mesic"];
if ($rok=='13') {$rok=2013;};
if ($rok=='14') {$rok=2014;};
if ($rok=='15') {$rok=2015;};
if ($rok=='16') {$rok=2016;};
if ($rok=='17') {$rok=2017;};
if ($rok=='18') {$rok=2018;};
$hostname_test = "....";
$database_test = "....";
$username_test = ".....";
$password_test = "......";
$db = mysql_connect($hostname_test, $username_test, $password_test);
mysql_select_db($database_test,$db);
$vysledek = mysql_query($result);
$data = mysql_query("SELECT SUM(SPOTREBA) AS celkova FROM spotreba WHERE `MERAK`='".$merak."'  AND YEAR(DATUM)='".$rok."' AND MONTH(DATUM)='".$mesic."'  ",$db); 
$zaznam = mysql_fetch_array($data);
$pren = str_replace(",", ".", $zaznam["celkova"]);
return $pren;
}
?>
RastyAmateur
Profil
Nevím, co je line 87 a line 88, nejsem si jist, zda-li mé řešení bude k něčemu, ale jsem si (téměř) jist, že i když to asi není ta chyba, kterou to hlásí, tak že bez toho to fungovat nebude...

<?
$hostname_test = "....";
$database_test = "....";
$username_test = ".....";
$password_test = "......";
$db = mysql_connect($hostname_test, $username_test, $password_test);
mysql_select_db($database_test,$db);
 
function AktualniMesicSoucet($merak){
global $hostname_test;
global $database_test;
global $username_test;
global $password_test;
global $_GET;
$rok=$_GET["rok"];
$mesic=$_GET["mesic"];
if ($rok=='13') {$rok=2013;};
if ($rok=='14') {$rok=2014;};
if ($rok=='15') {$rok=2015;};
if ($rok=='16') {$rok=2016;};
if ($rok=='17') {$rok=2017;};
if ($rok=='18') {$rok=2018;};
$vysledek = mysql_query($result);

# co je $result? Nevidím to definované.

$data = mysql_query("SELECT SUM(SPOTREBA) AS celkova FROM spotreba WHERE `MERAK`='".$merak."'  AND YEAR(DATUM)='".$rok."' AND MONTH(DATUM)='".$mesic."'  ",$db); 
$zaznam = mysql_fetch_array($data);
$pren = str_replace(",", ".", $zaznam["celkova"]);
return $pren;
}
?>

Opakuji: V tomto řešení si opravdu nejsem jist. Můžeš to vyzkoušet, ale je dost možné, že to nepomůže!


Ještě jsem hledal, a asi by mělo stačit toto:

<?
$hostname_test = "....";
$database_test = "....";
$username_test = ".....";
$password_test = "......";
$db = mysql_connect($hostname_test, $username_test, $password_test);
mysql_select_db($database_test,$db);
 
function AktualniMesicSoucet($merak){
global $db;
global $_GET;
$rok=$_GET["rok"];
$mesic=$_GET["mesic"];
if ($rok=='13') {$rok=2013;};
if ($rok=='14') {$rok=2014;};
if ($rok=='15') {$rok=2015;};
if ($rok=='16') {$rok=2016;};
if ($rok=='17') {$rok=2017;};
if ($rok=='18') {$rok=2018;};
$vysledek = mysql_query($result);
 
# co je $result? Nevidím to definované.
 
$data = mysql_query("SELECT SUM(SPOTREBA) AS celkova FROM spotreba WHERE `MERAK`='".$merak."'  AND YEAR(DATUM)='".$rok."' AND MONTH(DATUM)='".$mesic."'  ",$db); 
$zaznam = mysql_fetch_array($data);
$pren = str_replace(",", ".", $zaznam["celkova"]);
return $pren;
}
?>
mimochodec
Profil
RastyAmateur:
function AktualniMesicSoucet($merak){
global $db;
global $_GET;
$rok=$_GET["rok"];
$mesic=$_GET["mesic"];

To bych asi diplomaticky nazval ne dobrou programátorskou praxí. Teď nechci rozebírat, kdy je dobré global používat, ale toto není ten případ. Není nejmenší důvod si v rámci funkce sahat pro GET nebo pro připojení k databází přes global. Hodnoty z GETu je rozhodně lepší načíst a ošetřit mimo tu funkci a do ní předat jako parametr.
Tzn.

function AktualniMesicSoucet($merak, $rok, $mesic, $db){
Přičemž je diskutabilní, jestli je potřeba předávat $db a jestli ten dotaz neupravit, jak píšu v #15 a ten $rok a $mesic nezpracovat mimo funkci do jedné hodnoty.
RastyAmateur
Profil
mimochodec:
Regoval jsem na to, proč mu to hází chybu. Rok a měsíc bych ošetřil také mimo funkci - ba i víc, ošetřil bych to i jinak.

global $db; bych klidně nechal.


Ovšem já bych to nechal proto, protože se ve funkcích snažím mít co nejméně parametrů. Je to pro mě osobně přehlednější. Co se ve funkci nemění prostě do parametrů funkce necpu...

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