Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: zapytanie z data
Forum PHP.pl > Forum > Bazy danych > MySQL
veyron
witam
mamy tabele, w ktorej jest pole daty - pobierany miesiac za pomoca date format(%c) oraz pole kwota.
chcialbym zrobic zestawienie kwot dla danych miesiecy, czyli otrzymac tabelke w postaci:
miesiac | 01-2010 | 02-2010 itd...
kwota | 0 | 20 itd...
przy czym moze sie zdazyc, ze dany miesiac nie wystepuje w bazie i wowczas chcialbym otrzymac kwote 0.
i teraz mam pytanie - czy jest mozliwe, zeby jesli dany miesiac nie wystepuje w bazie np. styczen 2010, to zeby baza zwrocila kwote 0 dla tego miesiaca ? jesli tak, to w jaki sposob ?
pozdrawiam
pmir13
Może napisz dokładnie co masz w tabeli z przykładowymi danymi i jakiego spodziewasz się wyniku dla tych konkretnych danych.
veyron
to moze podam na konkretnym przykladzie:
w tabeli jest data (d.m.r) i ilosc zlecen odpowiadajaca danej dacie (sa jeszcze inne komorki, ale dla tego przykladu nie sa az tak istotne teraz), czyli dla przykladu:
data | ilosc zlecen
01.02.2010 | 15
15.02.2010 | 22
03.04.2010 | 2
03.04.2010 | 8

i teraz chce zestawienie za dany rok np. 2010 w tabelce, ktora ma format (dane dla ww przykladu):
miesiac | 01.2010 | 02.02010 | 03.2010 | 04.2010 | itd.
ilosc zlecen | 0 | 37 | 0 | 10 | itd.

poczatkowo mialem taki kod (rozwiazanie nr 1):
  1. $sql->query('SELECT COUNT(id_zlecenie) AS ilosc, DATE_FORMAT(data_z, \'%m-%Y\') AS data FROM zlecenie INNER JOIN zleceniodawca AS firma3 ON zlecenie.id_zb=firma3.id_fast INNER JOIN firma AS firma1 ON zlecenie.id_zleceniobiorca=firma1.id_firma INNER JOIN firma AS firma2 ON zlecenie.id_zleceniodawca=firma2.id_firma WHERE czy_anulowane = 0 GROUP BY data ORDER BY id_zlecenie ASC');
  2.  
  3.  
  4.  
  5. print '<div class="statystyki">
  6. <table>
  7. <caption>Ilość zleceń w danych miesiącach</caption>
  8. <tr><th>Miesiąc</th>';
  9.  
  10. while($statystyki = $sql->fetchArray()) {
  11.  
  12. <th>'.$statystyki['data'].'
  13. </th>';
  14. }
  15.  
  16. //czyli zapytanie i wyplucie wiersza z miesiacami 02.2010| 04.2010
  17.  
  18. print '</tr>
  19.  
  20. <tr><td>ilość zleceń</td>';
  21.  
  22. $sql->query('SELECT COUNT(id_zlecenie) AS ilosc, DATE_FORMAT(data_z, \'%m-%Y\') AS data FROM zlecenie INNER JOIN zleceniodawca AS firma3 ON zlecenie.id_zb=firma3.id_zb INNER JOIN firma AS firma1 ON zlecenie.id_zleceniobiorca=firma1.id_firma INNER JOIN firma AS firma2 ON zlecenie.id_zleceniodawca=firma2.id_firma WHERE czy_anulowane = 0 GROUP BY data ORDER BY id_zlecenie ASC');
  23.  
  24. while($statystyki = $sql->fetchArray()) {
  25.  
  26. <td>'.$statystyki['ilosc'].'
  27. </td>';
  28. }
  29.  
  30. //czyli ponownie to samo zapytanie i wyplucie wiersza z iloscia zlecen w postaci 37 | 10 (odpowiadajace odpowiednim miesiacom z poprzedniego zapytania)
  31.  
  32. print '</tr>
  33. </table></div>';

czyli, w zasadzie zapytanie do bazy bylo 2 razy to samo, ale wynik byl w tabeli, ktora:
po 1. ciagnela sie w nieskonczonosc i nie mozna bylo jej przelamac np jak zaczal sie nowy rok
po 2. wynik pomijal miesiace, gdzie byla ilosc 0

poradzilem sobie w taki sposob (rozwiazanie nr 2):
  1. print '<div class="statystyki">
  2. <h1>Ilość zleceń w danych miesiącach</h1>
  3. ';
  4. $zapytanie = mysql_query('SELECT DATE_FORMAT(data_zaladunku, \'%Y\') AS rok FROM zlecenie INNER JOIN zleceniodawca AS firma3 ON zlecenie.id_zb=firma3.id_zb INNER JOIN firma AS firma1 ON zlecenie.id_zleceniobiorca=firma1.id_firma INNER JOIN firma AS firma2 ON zlecenie.id_zleceniodawca=firma2.id_firma WHERE czy_anulowane = 0 GROUP BY rok ORDER BY rok DESC');
  5.  
  6. //pobranie wszystkich lat, dla ktorych istnieja dane w bazie, ponizej petla tworzaca tabele z zestawieniem dla konkretnego roku
  7.  
  8. while($statystyki_lata = mysql_fetch_assoc($zapytanie)) {
  9.  
  10. $statystyki_rok = $statystyki_lata['rok'];
  11.  
  12. <table>
  13. <caption>Rok '.$statystyki_rok.'</caption>
  14. <tr><th>Miesiąc</th>';
  15. $miesiac = 1;
  16. while($miesiac != 13) {
  17.  
  18.  
  19. <th>'.$miesiac.'-'.$statystyki_rok.'
  20. </th>';
  21. $miesiac++;
  22. }
  23.  
  24. // wypisanie wszystkich miesiecy dla danego roku
  25.  
  26. print '</tr>
  27.  
  28. <tr><td>ilość zleceń</td>';
  29.  
  30.  
  31.  
  32. $miesiac = 1;
  33. while($miesiac != 13) {
  34. $sql->query('SELECT COUNT(id_zlecenie) AS ilosc, DATE_FORMAT(data_z, \'%c-%Y\') AS data, DATE_FORMAT(data_z, \'%c\') AS miesiac, DATE_FORMAT(data_z, \'%Y\') AS rok FROM zlecenie INNER JOIN zleceniodawca AS firma3 ON zlecenie.id_zb=firma3.id_zb INNER JOIN firma AS firma1 ON zlecenie.id_zleceniobiorca=firma1.id_firma INNER JOIN firma AS firma2 ON zlecenie.id_zleceniodawca=firma2.id_firma WHERE czy_anulowane = 0 AND DATE_FORMAT(data_zaladunku, \'%Y\') = \''.$statystyki_rok.'\' AND DATE_FORMAT(data_zaladunku, \'%c\') = \''.$miesiac.'\' GROUP BY data ORDER BY id_zlecenie ASC');
  35. $statystyki = $sql->fetchArray();
  36.  
  37. <td>';
  38. if (!empty($statystyki['ilosc'])) {
  39. print $statystyki['ilosc'];
  40. }
  41. else {
  42. print '0';
  43. }
  44.  
  45. </td>';
  46. $miesiac++;
  47. }
  48.  
  49. // wypisanie ilosci zlecen dla konkretnego miesiaca,
  50.  
  51. print '</tr>
  52. </table>';
  53. }
  54. print '</div>';

i w zasadzie dziala idealnie, bo otrzymuje to co chcialem - jest tylko jedno, ale - dla kazdego miesiaca jest zapytanie do bazy, wobec czego dla dluzszego okresu (np. pare lat) zapytan sie zrobi wieksza ilosc,
i teraz pytanie brzmi czy moze da sie zrobic to jakos latwiej/prosciej/mniejsza iloscia zapytan (zmieniajac niekoniecznie samo zapytanie do bazy, ale moze rowniez sam kod php/html)?
mysle, ze zagadnienie jest dosc ogolne, bo wystepuje wszedzie tam gdzie chcemy otrzymac dane statystyczne w formie tabeli z podzialem na dane miesiace, przy czym wystepuja miesiace, ktore w bazie nie istnieja (bo bylo 0 zlecen).

ehh troche sie rozpisalem biggrin.gif

w kazdym razie dzieki za zainteresowanie tematem smile.gif
pozdrawiam.
pmir13
Szukasz optymalizacji w niewłaściwym miejscu.

Nie masz takiej tabeli jak napisałeś na początku, te statystyki i tak sobie liczysz na podstawie tabeli zlecenie.
Nie podałeś jak naprawdę te tabele wyglądają, właściwie to nie wiadomo nawet po co te wszystkie łączenia, skoro i tak informacji o firmach nie potrzebujesz.
Wygląda na to, że wszystko co trzeba wiedzieć masz w tabeli zlecenia i tylko na niej powinieneś operować.

Najwięcej czasu nie będzie pochłaniać wykonanie iluś tam zapytań zwracających po 1 linijce zamiast dużego zwracającego wszystko, tylko liczenie zleceń w obrębie jednego miesiąca. Jeżeli baza będzie duża, to liczenie tego bez indeksów będzie głównym źródłem spowolnień. Proponowałbym utworzenie indeksu na data_z w zleceniach, a w zapytaniach operowanie wyłącznie na porównaniach typu mniejsze, większe, równe itp. Czyli dla podanego zakresu dat do wypisania statystyk jaki sobie użytkownik zażyczy liczysz kolejne miesiące w php, w ten sposób by dla każdego miesiąca już przed złożeniem zapytania mieć dwie ograniczające daty, które możesz porównać bez konieczności formatowania dat w sql. Czyli na przykład gotowe zapytanie dla 04.2011 powinno wyglądać tak:
  1. SELECT count(*) AS ilosc_zlecen FROM zlecenie WHERE data_z >= '2011-04-01' AND data_z < '2011-05-01'


Jeśli jednak upierasz się, by wykonać tylko jedno zapytanie, to musisz albo tworzyć tymczasową tabelę w procedurze, albo zdenormalizować trochę swoją bazę, wykorzystując dodatkową tabelę miesiace.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.