Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] Uzupełnienie luk tablicy
Forum PHP.pl > Forum > PHP
markonix
Ciężko mi nazwać temat bo nie mam pojęcia jak to nazwać, a ogólnie problem prosty.

Dane z bazy wyciągnięte dzięki GROUP BY i funkcji date ORAZ SUM

type date SUM
xxx 2008-03-27 1
xxx 2008-03-30 6
xxx 2008-04-04 1
xxx 2008-04-05 2
xxx 2008-04-06 8
xxx 2008-04-07 2
xxx 2008-04-08 3
xxx 2008-04-09 2

(xxx to jakiś typ usługi, data zamówienia i suma w danym dniu).
Dane pobieram do wykresu, który przyjmuje wartości w formie json co jest mniej istotne.
Istotne mianowicie jest, że podaje je po przecinku, a wykres sam podstawia pod daty i prowadzi to do błędu w przypadku przerw.

Chciałbym dostać tablice, z wszystkimi indeksami wraz z lukami z wartością ZERO.
type date SUM
xxx 2008-03-27 1
xxx 2008-03-28 0
xxx 2008-03-29 0

xxx 2008-03-30 6
itd.

Wykres przyjmuje wartości w postaci 1, 0, 0, 6 i można się domyśleć, że brak zer spowoduje przesunięcie.

Może to się da zrobić na poziomie samego zapytania (mysql), jeśli nie to jak to zrobić po stronie php?
Oczywiście mogę puścić pętle iterującą po kolejnych dniach ale to wygeneruje kilkaset zapytań (tyle ile dni) do bazy - raczej mało optymalne.
Poza tym tych typów jest kilka i ostatecznie chciałbym otrzymać kilka tablic - oddzielnie dla każdego.
tehaha
można to zrobić jednym zapytaniem

1. Pobierasz te dane i wrzucasz do tablicy, gdzie klucz to będzie data, a wartość to co masz czyli:

['2008-03-27'] => xxx 2008-03-27 1
['2008-03-30'] => xxx 2008-03-30 6
['2008-04-04'] => xxx 2008-04-04 1

2. następnie używając modyfikacji tej funkcji http://prajapatinilesh.wordpress.com/2009/...using-php-code/

wygenerujesz tablicę z kluczami do wszystkich data z przedziału i wartościami 0

3. używając funkcji http://php.net/manual/en/function.array-merge.php, połączysz obie tablice, w ten sposób te daty, które posiadają wartości nadpiszą te z zerami czyli ['2008-03-27'] => 0 zostanie zastąpione przez ['2008-03-27'] => xxx 2008-03-27 1, dla pozostałych zostanie 0

w ten sposób otrzymasz tablicę z datami z przedziału od/do , z brakującymi wartościami jako 0

tutaj masz modyfikację:

  1. <?php
  2. $fromDate = '2010-01-14';
  3. $toDate = '2010-04-14';
  4.  
  5. $dateMonthYearArr = array();
  6. $fromDateTS = strtotime($fromDate);
  7. $toDateTS = strtotime($toDate);
  8.  
  9. for ($currentDateTS = $fromDateTS; $currentDateTS <= $toDateTS; $currentDateTS += (60 * 60 * 24))
  10. {
  11. // use date() and $currentDateTS to format the dates in between
  12. $dateMonthYearArr[date("Y-m-d",$currentDateTS)] = 0;
  13. //print $currentDateStr.”<br />”;
  14. }
  15.  
  16. echo "<pre>";
  17. print_r($dateMonthYearArr);
  18. echo "</pre>";
  19. ?>
markonix
Dziękuje, zaraz spróbuje.

Tymczasem wpadłem na podobny pomysł ale po stronie mysql.
Stworzyć bazę o strukturze analogicznej do tablicy z pętli Twojego skryptu (data i zero), a następnie też łączenie tylko w przypadku baz chodzi oczywiście o JOIN.

tehaha
na tablicy będzie wydajniej, nie ma sensu obciążać bazy danych do takich operacji, zwłaszcza, że możesz sobie to ładnie opakować w funkcje i wywoływać jedną linijką kodu
markonix
Miałem pewne opory ze względu na to, że tablica ma pewne ograniczenia pamięciowe i kiedyś skrypt mi się wysypał stąd uraz smile.gif

Twoje porady się sprawdziły choć array_merge nie do końca spełniło oczekiwania co do drugiego indeksu - typu usługi.
Ładowało zerami tylko gdy nie było żadnej usługi, żadnego typu. Gdy choć jedna była w danym dniu to już omijał i zostawiał jak było.
Ale byłem pewien, że ktoś chciał osiągnąć taki efekt jak ja i wypróbowałem wszystkie funkcje na php.net
Gdzieś za 5tym razem trafiłem:

  1. function array_overlay($a1,$a2)
  2. {
  3. foreach($a1 as $k => $v) {
  4. if(!array_key_exists($k,$a2)) continue;
  5. if(is_array($v) && is_array($a2[$k])){
  6. $a1[$k] = array_overlay($v,$a2[$k]);
  7. }else{
  8. $a1[$k] = $a2[$k];
  9. }
  10. }
  11. return $a1;
  12. }


Dzięki za pomoc.
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.