Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][SQL]zliczanie wybranych danych
Forum PHP.pl > Forum > Przedszkole
wach12
Witam!

Próbuję zrkbić sumowanie wybranych danych z sql

Przykładowa tabela:
ID|nazwa_produktu|energia_produktu|bialko_produktu
1 |Mąka | 2000 |100
2 |Woda | 2000 |100
3 |Margaryna | 2000 |100
4 |Marmolada | 2000 |100

chciałbym zsumować energie_produktu dla np. Mąki i Margaryny (dane porównuję za pomocoów post)

  1.  
  2. $s1=$_POST['skladnik'];
  3. $s2=$_POST['skladnik0'];
  4. $s3=$_POST['skladnik1'];
  5. $s4=$_POST['skladnik2'];
  6. $s5=$_POST['skladnik3'];
  7. $s6=$_POST['skladnik4'];
  8.  
  9.  
  10.  
  11.  
  12.  
  13. $zapisz = $_POST['zapisz'];
  14.  
  15. IF(isset($zapisz)){
  16.  
  17. $stmt = $pdo_db -> prepare('SELECT * FROM `produkty` WHERE `nazwa_produktu` = :nazwa_produktu '); // 2
  18. $stmt -> bindValue(':nazwa_produktu', $_POST['skladnik'], PDO::PARAM_INT);
  19. $stmt -> execute(); // 3
  20.  
  21. IF($details = $stmt -> fetch()) // 4
  22. {
  23. $test=$details['energia_produktu'];
  24.  
  25.  
  26. echo '<hr/>
  27. <p><b>Energia produktu:</b> '.$suma.'</p>
  28. ';
  29. }
  30. else
  31. {
  32. echo '<hr/><p>Przepraszamy, podany rekord nie istnieje!</p>';
  33. }
  34. $stmt -> closeCursor();
  35. }
  36.  
  37.  
  38.  


SmokAnalog
Chcesz wypisać tylko sumę czy masz gdzieś listę tych wybranych produktów? Bo jeśli to pierwsze, to możesz zrobić zapytanie z sum(), a jeśli drugie, to możesz zsumować sobie w pętli, bo i tak masz potrzebne rekordy.
wach12
Tylko sume próbowałem z sum() ale nie wychodzi
SmokAnalog
Pokaż jak próbowałeś.
wach12
  1. IF(isset($zapisz)){
  2.  
  3.  
  4. $stmt = $pdo_db -> prepare('SELECT sum(energia_produktu) FROM `produkty` WHERE `nazwa_produktu` = :nazwa_produktu AND `nazwa_produktu2` = :nazwa_produktu AND `nazwa_produktu` = :nazwa_produktu3'); // 2
  5. $stmt -> bindValue(':nazwa_produktu', $_POST['skladnik'], PDO::PARAM_INT);
  6. $stmt -> bindValue(':nazwa_produktu2', $_POST['skladnik0'], PDO::PARAM_INT);
  7. $stmt -> bindValue(':nazwa_produktu3', $_POST['skladnik1'], PDO::PARAM_INT);
  8. $stmt -> execute(); // 3
  9.  
  10. IF($details = $stmt -> fetch()) // 4
  11. {
  12. $suma = $details['sum(energia_produktu)'];
  13.  
  14.  
  15. echo '<hr/>
  16. <p><b>Energia produktu:</b> '.$suma.'</p>
  17. ';
  18. }
  19. else
  20. {
  21. echo '<hr/><p>Przepraszamy, podany rekord nie istnieje!</p>';
  22. }
  23. $stmt -> closeCursor();
  24. }
SmokAnalog
Twoje zapytanie wyszukuje produkty, których nazwa to jednocześnie A, B i C. Czyli to się nigdy nie sprawdza, gdy A != B != C. Rozumiesz?

Zamiast tego, zrób zapytania na zasadzie:

  1. SELECT sum(`energia_produktu`)
  2. FROM `produkty`
  3. WHERE `nazwa_produktu` IN ('Jabłko', 'Sernik', 'Czekolada')
wach12
Nie zabardzo tak mogę .

Juz pokazuję na czym to polega:

Wpisujemy do formularza dane np.woda i Mąka które sa filtrowane za pomoca autocompleat i sprawdzane czy sa w bazie jezeli sa w bazie skrypt przechodzi dalej.

Następnie muszę zliczyć ich energie ktora jest podana w bazie, a dane ma filtrowac z pomoca formularza czyli jak wpisze w formularzu Mąka i Woda to ma zliczyc energie mąki i wody.



A robiąc w ten sposób zlicza mi ze wszystkich wierszy kiedy j bym chcial tylko z wybranych

  1. IF(isset($zapisz)){
  2.  
  3.  
  4. $stmt = $pdo_db -> prepare('SELECT sum(energia_produktu) FROM `produkty` WHERE `nazwa_produktu` IN (`nazwa_produktu` = :nazwa_produktu, `nazwa_produktu` = :nazwa_produktu2, `nazwa_produktu` = :nazwa_produktu3)'); // 2
  5. $stmt -> bindValue(':nazwa_produktu', $_POST['skladnik'], PDO::PARAM_INT);
  6. $stmt -> bindValue(':nazwa_produktu2', $_POST['skladnik0'], PDO::PARAM_INT);
  7. $stmt -> bindValue(':nazwa_produktu3', $_POST['skladnik1'], PDO::PARAM_INT);
  8. $stmt -> execute(); // 3
  9.  
  10. IF($details = $stmt -> fetch()) // 4
  11. {
  12. $suma = $details['sum(energia_produktu)'];
  13.  
  14.  
  15. echo '<hr/>
  16. <p><b>Energia produktu:</b> '.$suma.'</p>
  17. ';
  18. }
  19. else
  20. {
  21. echo '<hr/><p>Przepraszamy, podany rekord nie istnieje!</p>';
  22. }
  23. $stmt -> closeCursor();
  24. }
  25.  
  26.  
SmokAnalog
Nie wiem z czym masz problem. Po prostu zrób tak, żeby zapytanie otrzymało odpowiednie IN (a, b, ...).
wach12
Tak też zrobiłem ale zlicza mi wszystkie wiersze a nie tylko 3 tak jak chce

obecnie mam w bazie 12 pozycji i w echo mi zwraca 12 zamiast 3 zakładajac ze dla kazdego energia jest rowna 1

Zrobiłem to w jeszcze inny sposób tylko nie działa ma ktos jakis pomysł questionmark.gif

  1. $skladniki = [];
  2. for ($num=0; $num < 20; $num++) {
  3. if (!is_int($_POST['skladnik'.$num])) {
  4. break;
  5. }
  6.  
  7. $skladniki[] = $_POST['skladnik'.$num];
  8. }
  9. if (isset($zapisz)) {
  10. $stmt = $pdo_db -> prepare('SELECT energia_produktu FROM `produkty` WHERE `nazwa_produktu` IN (:skladniki)');
  11. $stmt->bindValue(':skladniki', implode($skladniki, ','), PDO::PARAM_STR);
  12. $stmt->execute(); // 3
  13. $result = $stmt->fetch();
  14.  
  15. if ($result === null) {
  16. echo '<hr/><p>Przepraszamy, podany rekord nie istnieje!</p>';
  17. die();
  18. }
  19.  
  20. $suma = 0;
  21. foreach ($result as $item) {
  22. $suma+= $item['energia_produktu'];
  23. }
  24. echo '<p><b>Energia produktu:</b> '.$suma.'</p>';
  25. }
  26.  
SmokAnalog
W chwili obecnej, Twoje zapytanie wygląda tak:
  1. SELECT `energia_produktu` FROM `produkty` WHERE `nazwa_produktu` IN ('Jabłko,Banan,Czekolada')


Jest już prawie dobrze. Operator IN w SQL nie przyjmuje pojedynczego stringa ze słowami oddzielonymi przecinkami, ale osobnych stringów. Powinno być tak:
  1. SELECT `energia_produktu` FROM `produkty` WHERE `nazwa_produktu` IN ('Jabłko', 'Banan', 'Czekolada')


Widzisz różnicę? Musisz dynamicznie podpiąć te parametry, to nie jest aż takie znowu trywialne. Dam Ci podpowiedź. Najłatwiej będzie Ci to zrobić w taki sposób:
  1. $stmt = $pdo_db -> prepare('SELECT energia_produktu FROM `produkty` WHERE `nazwa_produktu` IN (?, ?, ?)');
  2. $stmt->execute(['Jabłko', 'Banan', 'Czekolada']);


Najtrudniejsza część to dokleić te znaki zapytania w odpowiedniej liczbie, ale dasz radę.
viking
Tu masz opisane jak to zrobić.
SmokAnalog
Dlaczego to durne array_fill przyjmuje indeks początkowy jako pierwszy parametr? Ciekawe w ilu przypadkach na 100 ktoś to ustawia na coś innego niż zero. Idiotyzm.
viking
A dlaczego durne i od ilu ma mieć indeks? Na logikę skladnia jest dobra chociaz pamiętam ze jak wtedy szukałem najlepszego rozwiązania to właśnie sporo w tym bylo błędów. Ale że ludzie nie czytają dokumentacji to ich problem.
SmokAnalog
Zupełnie się z Tobą nie zgadzam, viking. A już tym zdaniem "Ale że ludzie nie czytają dokumentacji to ich problem." osiągnąłeś szczyt ignorancji.

Głupawa deklaracja array_fill nie jest niczym uzasadniona. Ta funkcja jest po prostu źle zaprojektowana. Jej deklaracja powinna wyglądać tak:
  1. function array_fill(mixed $value, int $num, int $start_index = 0)


Lub tak:
  1. function array_fill(int $num, mixed $value, int $start_index = 0)


Przy czym moim zdaniem bardziej naturalna jest pierwsza możliwość, bo najpierw chce się (ja chcę?) podać co ma być w tej tablicy, a potem ile. Nie na odwrót.

Dlaczego uważasz, że w porządku jest $start_index jako pierwszy parametr? Pokusiłbym się nawet o zdanie, że tego parametru mogłoby całkowicie nie być. Po co niby mam zaczynać od jakiegokolwiek indeksu numerycznego? Jedyny sensowny przykład jaki wymyśliłem, to taki:
  1. $cats = array_fill(0, 'Franek', 3) + array_fill(3, 'Bubek', 5);


Ale i tak jest głupawy, bo lepiej by było zrobić to tak:
  1. $cats = array_merge(array_fill('Franek', 3), array_fill('Bubek', 5));


Jak już mam mieć wpływ na indeks w array_fill to o wiele lepszy byłby argument typu callable:
  1. function array_fill(mixed $value, int $num, callable $keys)


Otrzymywałby wartość i indeks jako parametry i żeby użyć go w durnowaty sposób zaproponowany przez array_fill, mielibyśmy na przykład:
  1. $cats = array_fill('Bubek', 5, function ($value, $index) {
  2. return $index + 3;
  3. });


viking naprawdę uważasz, że funkcja array_fill jest sensownie zaprojektowana? o0
viking
Wszystkie argumenty są wymagane więc kolejność nie ma i tak żadnego znaczenia. Dla mnie obecna konstrukcja jest bardziej naturalna. Wolę indeksy numeryczne na początku a później dopiero wartości. Przykładowo:

  1. $this->getA(),
  2. (int) $this->getX(),
  3. długi callable
  4. );


Zdecydowanie łatwiej ogarnąć krótkie pierwsze, długie kolejne
SmokAnalog
Cytat(viking @ 11.11.2016, 11:49:31 ) *
  1. $this->getA(),
  2. (int) $this->getX(),
  3. długi callable
  4. );

Podaj mi sensowne uzasadnienie tego kodu. Tworzysz tablicę rozpoczynającą się od indeksu getA() zawierającą kilka identycznych callable? Nie. Po prostu nie.
viking
Co rozumiesz przez identycznych?
SmokAnalog
Nie wiem w sumie po co ta dyskusja, to jest jeden z tych przypadków, gdzie jestem pewien mojego punktu widzenia. Bardzo nie lubię, kiedy ktoś się wykazuje ignorancją i posługuje się argumentami na poziomie "o ich problem, że nie czytają dokumentacji". Jest to retoryka z rynsztoka.

Argumenty funkcji muszą być w sensownej kolejności, niestety PHP nie przestrzega tego paradygmatu, dlatego mamy np. array_map i array_filter, które mają je po prostu na odwrót. Takich przypadków jest o wiele więcej w PHP. Nie ma co tego bronić, bo to podpada pod fanatyzm i zaślepienie. Są to złe decyzje projektowe i oby kiedyś zostały naprawione.

Przykład z array_fill jest ewidentny. Tablica indeksowana n..m, gdzie n > 0, to w większości przypadków błąd projektowy aplikacji. Nie bez powodu w (prawie?) wszystkich innych językach nie ma nawet czegoś takiego jak tablica asocjacyjna, czasem są słowniki. Ale nikomu nie przychodzi do głowy słownik z kluczami np. 5, 6, 7 itd. Jest to egzotyczne zastosowanie, które owszem - może kiedyś znaleźć zastosowanie, ale nie należy dla tego osobliwego przypadku dawać - uwaga - obowiązkowego i pierwszego (exclamation.gif!) argumentu funkcji. Te zera w array_fill pewnie mają już jakąś mafię.
viking
Wybacz ale na pewno 90% problemów na tym forum wynika tylko i wyłącznie z tego że komuś nie chciało się zajrzeć do dokumentacji. To co funkcja zwraca to dla wielu osób już totalna abstrakcja. A i tak dokumentacja przeszła jakiś czas temu spory lifting i jest obecnie dużo bardziej czytelna. Lenistwa nie popieram więc dlaczego tego jednego zdania się po raz kolejny uczepiłeś? Błędy w nazewnictwie i kolejności znane są od wielu wielu (żeby daleko nie szukać mysql_query / pg_query) lat więc nic nowego. Nie ma w innych językach tablic asocjacyjnych / słowników? Python, C++, Perl. Jakoś we wszystkich występuje.
SmokAnalog
Cytat(viking @ 11.11.2016, 13:02:59 ) *
Wybacz ale na pewno 90% problemów na tym forum wynika tylko i wyłącznie z tego że komuś nie chciało się zajrzeć do dokumentacji. (...) Lenistwa nie popieram więc dlaczego tego jednego zdania się po raz kolejny uczepiłeś?

Uciekam z tego tematu, bo robi się niebezpiecznie idiotycznie.
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.