Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Kaskadowe sumowanie
Forum PHP.pl > Forum > Bazy danych > MySQL
DeyV
Mam zapytanie które zwraca mi mniej więcej taki wynik
Kod
id | nazwa           | ile

---+-----------------+----

1  | poniedziałek    | 1

2  | wtorek          | 3

3  | środa           | 5

A teraz chciałbym przy pomocy jednego zapytania w każdym z rekrodów otrzymać wartość sumującą wszystkie poprzednie pola ile (wraz z aktualnym)
np.
Kod
id | nazwa           | ile  | wynik

---+-----------------+------+----

1  | poniedziałek    | 1    | 1

2  | wtorek          | 3    | 4

3  | środa           | 5    | 9

Maiłem nadzieję, że wystrczy zapytanie typu:
[sql:1:eb3e8c2ddf]
SELECT id, nazwa, ile
@wynik := ile +
if( @wynik , @wynik , 0 ) FROM `tabela`[/sql:1:eb3e8c2ddf]
jednak to nie to.
Can You help me?
spenalzo
Raczej się nie da, gdyż wszystko co obliczasz to w obrębie jednego wiersza uzyskanego z zapytania, więc za każdym razem @wynik będzie miało wartość NULL.

A nie możesz dać po prostu [sql:1:b21ae05ba6]... SUM(ile) AS ilosc[/sql:1:b21ae05ba6] ?
adwol
Na początku zmienna ma wartość NULL, a jak dodasz do NULLa jakąkolwiek wartość to dalej będzie to NULL.
[sql:1:b38055d97a]select id, nazwa, ile, if(@a is not null,@a:=@a+id,@a:=id) as wynik from tabela
[/sql:1:b38055d97a]
spenalzo
A nie prościej tak:
[sql:1:91ffe514ab]select id, nazwa, ile, IFNULL(@a:=@a+id,@a:=id) AS wynik from tabela
[/sql:1:91ffe514ab]
DeyV
co do problemu z null to się zgadza.
Choć moje rozwiązanie, tj. if( @wynik , @wynik , 0 ) również radziło sobie z tym problemem (choć wiem, ze to nie jest prawidłowy sposób na sprawdzanie czy dana wartość jest równa NULL

Szkoda tylko, że spenalzo miał racje w pierwszym postcie, czyli że każdy wiersz jest liczony 'od zera'. Czy nie można tego w jakiś spoób przeskoczyć?
FiDO
[sql:1:99adda36a1]SELECT @wynik := 0;[/sql:1:99adda36a1]
+
[sql:1:99adda36a1]SELECT id, nazwa, ile
@wynik := @wynik + ile
FROM `tabela`
[/sql:1:99adda36a1]
adwol
Cytat
Szkoda tylko, że spenalzo miał racje w pierwszym postcie, czyli że każdy wiersz jest liczony 'od zera'. Czy nie można tego w jakiś spoób przeskoczyć?

Nie rozumiem w czym problem. Taki wynik chciałeś uzyskać czy inny? Bo po Twoim przykładzie wydawało mi się, że chodzi Ci o to właśnie.
DeyV
Adwol, fido, dokładnie czegoś takiego chciałem, ale ... ten zapis nie działa :/

To znaczy MySQL 4.0 w takim zapisie zawsze przyjmuje dla @a wartość 0, a wiec dana kolumna jest przepisaniem rekordu, który miał być zliczany.
Albo robię jakiś błąd...
Moje zapytanie: [sql:1:c325a57191]SELECT nazwa, wektor,
if(@a IS NOT null, @a:=@a+wektor ,@a:=wektor )
FROM `tabela` [/sql:1:c325a57191]
FiDO
Sprawdzales to moje?

Bo ja sprawdzalem propozycje adwola, spenalzo i one nie dzialaly (tzn. suma sie nie kumulowala), a "moim" sposobem poszlo i zliczylo tak jak chciales. Oczywisice musisz to wykonac w jedny polaczeniu, wiec jak testujesz to w phpmyadmin'ie to nie zadziala (chyba ze wlaczysz $cfg['PersistentConnections']).
adwol
Cytat
Bo ja sprawdzalem propozycje adwola, spenalzo i one nie dzialaly (tzn. suma sie nie kumulowala), a "moim" sposobem poszlo i zliczylo tak jak chciales.

No właśnie jest to ciekawe, bo tak nie działa:
Kod
mysql> select @a;

+------+

| @a   |

+------+

| NULL |

+------+

1 row in set (0.00 sec)



mysql> SELECT id, nazwa, ile, if(@a IS NOT null,@a:=@a+ile,@a:=ile) AS wynik from deyv;

+------+--------------+------+-------+

| id   | nazwa        | ile  | wynik |

+------+--------------+------+-------+

|    1 | poniedzialek |    1 |     1 |

|    2 | wtorek       |    3 |     3 |

|    3 | sroda        |    5 |     5 |

+------+--------------+------+-------+

3 rows in set (0.00 sec)

ale tak to już pójdzie:
Kod
mysql> select @a:=null;

+----------+

| @a:=null |

+----------+

| NULL     |

+----------+

1 row in set (0.00 sec)



mysql> SELECT id, nazwa, ile, if(@a IS NOT null,@a:=@a+ile,@a:=ile) AS wynik from deyv;

+------+--------------+------+-------+

| id   | nazwa        | ile  | wynik |

+------+--------------+------+-------+

|    1 | poniedzialek |    1 |     1 |

|    2 | wtorek       |    3 |     4 |

|    3 | sroda        |    5 |     9 |

+------+--------------+------+-------+

3 rows in set (0.00 sec)

Oba przykłady były robione niezależnie w osobnych sesjach.
Nie rozumiem, dlaczego jawne zainicjowanie zmiennej na NULL daje dobry wynik, skoro w/g manuala:
Cytat
Variables don't have to be initialised. They contain NULL by default and can store an integer, real, or string value.
DeyV
A jednak persistant conest nie ma w tym przypadku znaczenia, gdyż, ostatecznie, metoda podana przez Was, działa również na połączeniu zwykłym. Dlatego wielkie dzięki.
Ale zrozumieć logicznie tego się chyba nie da winksmiley.jpg
FiDO
Cytat
A jednak persistant conest nie ma w tym przypadku znaczenia

Alez ja nie pisalem, ze to ma znacznie, tylko ze jesli testujesz zapytania w phpmyadminie i podasz oba zapytania osobno nie majac persistent connection to wtedy nie zadziala (zmienne sa unikalne dla kazdego polaczenia).
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.