Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] [MySQL] jak to zrobić, policzyć?
Forum PHP.pl > Forum > Przedszkole
wlodek
mam dane w tabeli (id, data i pole liczbowe)

przykład danych z tabeli.

1 | 12-01-2010 | 456
2 | 10-02-2010 | 460
3 | 15-03-2010 | 489
.....


jak skontruować zapytanie, żebym otrzymał w wyniku taką tabelę jak poniżej z wynikami odejmowania kolejnych rekordów

12-01-2010 | 456 | 10-02-2010 | 460 | 4

wynik 4 ma byc rezultatem rekordów 1 i 2

nospor
To już sobie obrabiaj w php.
wlodek
A może jakaś podpowiedź.
Nie mam pojęcia jak się do tego zabrać, dlatego zadałem to pytanie.
thek
Bazę byś zajechał smile.gif Musiałbyś robić JOIN rekordu z rekordem następnym w kolejności (ostatni wylecieć musi bo będziesz joinować z nullem), potem zrobić różnicę tego rekordu drugiego i podstawowego. Z racji tego "połącz z następnym kolejnym" byś pojechał po bazie. Lepiej pobrać wszystkie rekordy i od drugiego zaczynając odejmuj wartość poprzednika (zapisuj ją w jakimś tempie czy coś w ten deseń).
nospor
Cytat
Nie mam pojęcia jak się do tego zabrać, dlatego zadałem to pytanie.
Zadales pytanie jak to zrobic w mysql (jakie zapytanie). Wyjasnilem ci wiec, ze prosto zrobisz to w php - sądzilem ze php na poziomie dodaj/odejmij to znasz smile.gif
phpion
Cytat(nospor @ 6.10.2010, 09:49:27 ) *
To już sobie obrabiaj w php.

Aj tam, aj tam. Lubię takie zagadki, więc podam gotowca.

Rozwiązanie 1. Szybsze, ale numerowanie id musi iść po kolei. W przypadku luki zwróci niepoprawne wyniki:
  1. SELECT
  2. t1.`data` AS data1,
  3. t1.liczba AS liczba1,
  4. t2.`data` AS data2,
  5. t2.liczba AS liczba2,
  6. (IFNULL(t2.liczba, 0) - t1.liczba) AS roznica
  7. FROM
  8. odejmowanie AS t1
  9. LEFT JOIN odejmowanie AS t2 ON (t2.id = t1.id + 1)
  10. ;


Rozwiązanie 2. Wolniejsze, ale nie ma problemu z lukami w numeracji.
  1. SELECT
  2. t1.`data` AS data1,
  3. t1.liczba AS liczba1,
  4. t2.`data` AS data2,
  5. t2.liczba AS liczba2,
  6. (IFNULL(t2.liczba, 0) - t1.liczba) AS roznica
  7. FROM
  8. odejmowanie AS t1
  9. LEFT JOIN odejmowanie AS t2 ON (t2.id = (SELECT id FROM odejmowanie WHERE `data` > t1.`data` LIMIT 1))
  10. ;
wlodek
Cytat(nospor @ 6.10.2010, 10:01:23 ) *
Zadales pytanie jak to zrobic w mysql (jakie zapytanie). Wyjasnilem ci wiec, ze prosto zrobisz to w php - sądzilem ze php na poziomie dodaj/odejmij to znasz smile.gif


Dodaj/ Odejmij itd. znam. Chciałem otrzymać informację może nie jak to zrobić ale jak się do tego zabrać. Od czego zacząć.

Jedną opd. już otrzymałem, że zajechał bym baze danych - i to jest konkret bo wiem, że zapytania odpadają.

Cytat(phpion @ 6.10.2010, 10:10:12 ) *
Aj tam, aj tam. Lubię takie zagadki, więc podam gotowca.

Rozwiązanie 1. Szybsze, ale numerowanie id musi iść po kolei. W przypadku luki zwróci niepoprawne wyniki:
  1. SELECT
  2. t1.`data` AS data1,
  3. t1.liczba AS liczba1,
  4. t2.`data` AS data2,
  5. t2.liczba AS liczba2,
  6. (IFNULL(t2.liczba, 0) - t1.liczba) AS roznica
  7. FROM
  8. odejmowanie AS t1
  9. LEFT JOIN odejmowanie AS t2 ON (t2.id = t1.id + 1)
  10. ;


Rozwiązanie 2. Wolniejsze, ale nie ma problemu z lukami w numeracji.
  1. SELECT
  2. t1.`data` AS data1,
  3. t1.liczba AS liczba1,
  4. t2.`data` AS data2,
  5. t2.liczba AS liczba2,
  6. (IFNULL(t2.liczba, 0) - t1.liczba) AS roznica
  7. FROM
  8. odejmowanie AS t1
  9. LEFT JOIN odejmowanie AS t2 ON (t2.id = (SELECT id FROM odejmowanie WHERE `data` > t1.`data` LIMIT 1))
  10. ;



Dzięki, na szybkości mi nie zależy a wiadomo, że czasem jakieś id wyleci.
Zobaczę co mi wyjdzie z tego 2 rozwiązania.
phpion
Stosując rozwiązanie nr 2 na pewno warto dodać indeks na pole z datą. Ja bym jednak sugerował zastanowienie się nad dodaniem dodatkowej kolumny określającej kolejny numer rekordu (i ją bierzesz pod uwagę w JOIN). Wówczas odpada problem z lukami w numeracji id, ale równocześnie jest konieczność aktualizacji pola numeru rekordu. Można jednak napisać trigger, który robiłby to automatycznie przy dodawaniu/edycji/usuwaniu rekordów z tabeli. Jeśli jednak nie masz w tabeli kosmicznie dużo danych i faktycznie nie zależy Ci na wydajności to na chwilę obecną pozostałbym na Twoim miejscu przy rozwiązaniu nr 2 z założonym indeksem na pole daty.
thek
Rozwiązanie phpiona ma oczywiście sens w wypadku względnie normalnych i małych ilościach rekordów. Jeśli zaczniesz mieć jednak ogromne ich ilości to zawartość ujęta nawiasami w ON może być znacznie wolniejsza niż przepchnięcie tego na php. Wszystko zależy od ilości rekordów. Ogólnie wyglądałoby dla php coś w stylu:
  1. $temp = **sql*_fetch_assoc( $resource );
  2. while( $row = **sql*_fetch_assoc($resource) ) {
  3. $roznica = $row['liczba'] - $temp['liczba'];
  4. //tu robisz co chcesz z różnicą, wyświetlasz, przypisujesz dane do tablicy wynikowej... czy co tam chcesz robić
  5. $temp = $row;
  6. }
gdzie **sql*_fetch_assoc to dowolna funkcja pobierająca dane rekordu z wyniku.

Tak więc: pobieramy pierwszy rekord jako temp, potem w pętli pobieramy następny rekord i robimy odejmowanie między polami rekordu obecnego i tempa. Na koniec obecny staje się tempem dla kolejnego przejścia pętli.
wlodek
Dzięki koledzy! Oba przykłady działają.

Rekordów nie mam i raczej nie będzie dużo.
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.