Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wyciagniecie najmniejszej wartosci z bazy danych
Forum PHP.pl > Forum > PHP
arfer
Witam
Mam takie oto zapytanie do bazy danych ktore zwraca mi najmniejsza wartosc dla danego parametru (wyscig_name) i okreslonego uzytkownika. Wszystko dziala prawidlowo do czasu gdy chce dodac najmniejsza wartosc danego parametru bez podzialu na uzytkownikow (pogrubione). Problem jest taki ze zwraca mi 1 najmniejszy wynik w bazie i powtarza go na wszystkich parametrach. Jesli wyciagne go z nawiasu i dodam do reszty select to dziala ale podaje wyniki tylko wybranego kierowcy (where) a chce aby obok jego wynikow byly najmniejsze wyniki ze wszystkich kierowcow w bazie. Czy ktos wiec jak to zapisac?

  1. $result = dbquery("SELECT zespol_name, wyscig_id, MIN(wynik) AS wynik,
  2. (SELECT MIN(wynik) FROM ".DB_WYNIKI." WHERE sesja_id IN (1,2,3,4)) AS mini_wynik
  3. FROM ".DB_WYNIKI."
  4. LEFT JOIN ".DB_WYSCIGI." USING(wyscig_id)
  5. LEFT JOIN ".DB_ZESPOLY." USING(zespol_id)
  6. WHERE sesja_id IN (1,2,3,4) AND kierowca_id='".$_GET['kierowca_id']."'
  7. GROUP BY wyscig_name
  8. ");
muniekw
Próbowałeś zapisać użytkowników jako LEFT JOIN ?
arfer
Jaki mialoby to sens? Ja nie musze wyciagac zadnych informacji z tabeli kierowcy tylko z tabeli wyniki. Zrobilem skrypt ktory porownuje wartosci poszczegolnych kierowcow z najmniejszymi wartosciami w ogole. W bazie wyniki podane sa tylko id danego kierowcow po czym lacze go z konkretna osoba.

Chodzi mi o wyciagniecie minimalnej wartosci z bazy danych i teraz uwaga dla wybranego kierowcy i dla wszystkich kierowcow. Dopiero raczkuje w php i nie wiem jak zapisac drugie select min(wynik) tak aby ominac where dla kierowca_id ktore obowiazuje dla wszystkich pozostalych wartosci. Zapisalem to w nawiasie ale wtedy znajduje tylko jeden najmniejszy wynik a ja zrobilem tabele w ktorej pokazywane sa wyniki kazdego wyscigu. Zobrazuje to :

TAK CHCE ABY WYGLADALO
Wyscig 1 - minimalna wartosc kierowcy dla tego wyscigu* - minimalna wartosc w ogole dla tego wyscigu (np 2)**
Wyscig 2 - minimalna wartosc kierowcy dla tego wyscigu* - minimalna wartosc w ogole dla tego wyscigu (np 1)**
Wyscig 3 - minimalna wartosc kierowcy dla tego wyscigu* - minimalna wartosc w ogole dla tego wyscigu (np 3)**
itd.

* MIN(wynik) WHERE sesja_id IN (1,2,3,4) AND kierowca_id='".$_GET['kierowca_id']."'
** MIN(wynik) WHERE sesja_id IN (1,2,3,4)

TAK WYGLADA Z OBECNYM KODEM
Wyscig 1 - minimalna wartosc kierowcy dla tego wyscigu - minimalna wartosc w ogole ze wszystkich wyscigow (1)
Wyscig 2 - minimalna wartosc kierowcy dla tego wyscigu - minimalna wartosc w ogole ze wszystkich wyscigow (1)
Wyscig 3 - minimalna wartosc kierowcy dla tego wyscigu - minimalna wartosc w ogole ze wszystkich wyscigow (1)
itd.

Czy ktos mnie rozumie? tongue.gif
mortus
W podzapytaniu brakuje warunku, który określałby o jaki wyścig chodzi. Ciężko to zapytanie w ogóle pojąć bez informacji odnośnie struktury tabel i relacji, ale możliwe, że chodziłoby o coś takiego:
  1. SELECT w1.zespol_name, w1.wyscig_id, MIN(w1.wynik) AS wynik,
  2. (SELECT MIN(w2.wynik) FROM " . DB_WYNIKI . " w2 WHERE w2.sesja_id IN (1,2,3,4) AND w2.wyscig_id = w1.wyscig_id) AS mini_wynik
  3. FROM " . DB_WYNIKI . " w1
  4. LEFT JOIN " . DB_WYSCIGI . " USING(wyscig_id)
  5. LEFT JOIN " . DB_ZESPOLY . " USING(zespol_id)
  6. WHERE sesja_id IN (1,2,3,4) AND kierowca_id = '" . $_GET['kierowca_id'] . "'
  7. GROUP BY wyscig_name
muniekw
Pisząc odpowiedź chodziło mi o to, że LEFT JOIN wybiera rekordy jeśli warunek jest spełniony. Jeśli warunek nie istnieje to takich rekordów nie doklei.
mortus
Cytat(muniekw @ 30.04.2012, 15:06:08 ) *
Pisząc odpowiedź chodziło mi o to, że LEFT JOIN wybiera rekordy jeśli warunek jest spełniony. Jeśli warunek nie istnieje to takich rekordów nie doklei.

Nie w tym przypadku kolego. Tutaj złączenia są wykonywane najpierw, a warunek w klauzuli WHERE służy do wyselekcjonowania odpowiednich rekordów z już połączonych tabel. Warunek w klauzuli WHERE nie jest tutaj warunkiem złączenia tabel.
arfer
Jesli zapisze w Select w1.zespol_name to zwroci mi brak takiej kolumny w tabeli:

Unknown column 'w1.zespol_name' in 'field list'
mortus
Cytat(arfer @ 30.04.2012, 15:29:24 ) *
Jesli zapisze w Select w1.zespol_name to zwroci mi brak takiej kolumny w tabeli:

Unknown column 'w1.zespol_name' in 'field list'

A zobacz, co masz w trzeciej linijce zapytania, które napisałem. Tam dodajesz alias w1 dla tabeli DB_WYNIKI. Zrobiłeś to?
arfer
Tak. Teraz moj kod wyglada tak:
  1. $result = dbquery("SELECT w1.zespol_name, w1.wyscig_id, MIN(w1.wynik) AS wynik,
  2. (SELECT MIN(w2.wynik) FROM " . DB_WYNIKI . " w2 WHERE w2.sesja_id IN (1,2,3,4) AND w2.wyscig_id = w1.wyscig_id) AS mini_wynik
  3. FROM " . DB_WYNIKI . " w1
  4. LEFT JOIN ".DB_WYSCIGI." USING(wyscig_id)
  5. LEFT JOIN ".DB_ZESPOLY." USING(zespol_id)
  6. WHERE sesja_id IN (1,2,3,4) AND kierowca_id='".$_GET['kierowca_id']."'
  7. GROUP BY wyscig_name
  8. ");


Wiem w czym tkwi problem nie wiem jak go rozwiazac. Wszystkie wartosci w select sa ze soba powiazane dlatego robiac tabele z wyswietlanymi kolejno wynikami while ($data = dbarray($result)) wyswietla mi najnizsza wartosc danego kierowcy dla kazdego wyscigu a 2 min wynik odseparowalem w nawiasie i odczytuje to jako wybierz najnizsza wartosc w ogole a nie najnizsza wartosc dla danego wyscigu.
mortus
Cytat(arfer @ 30.04.2012, 15:40:57 ) *
Wiem w czym tkwi problem nie wiem jak go rozwiazac. Wszystkie wartosci w select sa ze soba powiazane dlatego robiac tabele z wyswietlanymi kolejno wynikami while ($data = dbarray($result)) wyswietla mi najnizsza wartosc danego kierowcy dla kazdego wyscigu a 2 min wynik odseparowalem w nawiasie i odczytuje to jako wybierz najnizsza wartosc w ogole a nie najnizsza wartosc dla danego wyscigu.

No przecież o tym pisałem w pierwszej odpowiedzi. Jak wyglądają tabele w bazie danych (przynajmniej tabela DB_WYNIKI, chociaż struktura pozostałych tabel również mogłaby się przydać). Funkcja dbarray() to Twoja własna funkcja? Jak ona wygląda?
arfer
Tak wyglada caly moj kod :

  1. $result = dbquery("SELECT w1.zespol_name, w1.wyscig_name, MIN(w1.wynik) AS wynik,
  2. (SELECT MIN(w2.wynik) FROM " . DB_WYNIKI . " w2 WHERE w2.sesja_id IN (1,2,3,4) AND w2.wyscig_id = w1.wyscig_id) AS mini_wynik
  3. FROM " . DB_WYNIKI . " w1
  4. LEFT JOIN ".DB_WYSCIGI." USING(wyscig_id)
  5. LEFT JOIN ".DB_ZESPOLY." USING(zespol_id)
  6. WHERE sesja_id IN (1,2,3,4) AND kierowca_id='".$_GET['kierowca_id']."'
  7. GROUP BY wyscig_name
  8. ");
  9.  
  10. if(dbrows($result) > 0)
  11.  
  12. echo "
  13. <table align='center' style=' border-collapse: collapse; margin-top: ' width='100%' bgcolor='#FFFFFF'>
  14. <tr>
  15. <td colspan='5' style='border: 1px solid black; border-collapse: collapse; padding: 10px;'><b>Przebieg kariery</b></td>
  16. </tr>
  17. <tr>
  18. <td style='border: 1px solid black; border-collapse: collapse; padding: 5px;'>Wyscig</td>
  19. <td style='border: 1px solid black; border-collapse: collapse; padding: 5px;'>Zespół</td>
  20. <td style='border: 1px solid black; border-collapse: collapse; padding: 5px;'>Indywidualny najlepszy czas</td>
  21. <td style='border: 1px solid black; border-collapse: collapse; padding: 5px;'>Najlepszy czas tygodnia</td>
  22. <td style='border: 1px solid black; border-collapse: collapse; padding: 5px;'>Strata</td>
  23. </tr>";
  24. while ($data = dbarray($result))
  25. {
  26. echo "
  27. <tr>
  28. <td style='border: 1px solid black; border-collapse: collapse; padding: 5px;'>".$data['wyscig_name']."</td>
  29. <td style='border: 1px solid black; border-collapse: collapse; padding: 5px;'>".$data['zespol_name']."</td>
  30. <td style='border: 1px solid black; border-collapse: collapse; padding: 5px;'>".$data['wynik']."</td>
  31.  
  32.  
  33.  
  34. <td style='border: 1px solid black; border-collapse: collapse; padding: 5px;'>".$data['mini_wynik']."</td>
  35. <td style='border: 1px solid black; border-collapse: collapse; padding: 5px;'>".(strata($max, $data['wynik']))."</td>
  36.  
  37. </tr> ";
  38.  
  39. }
  40.  
  41. echo "</table>";


Funkcja straty jest niewazna wiec jej nie kopiowalem. Skrypt pobiera rekordy z bazy wyniki gdzie sa kolumny sesja_id (wezmie tylke te gdzie bedzie 1,2,3,4) zespol_id i wyscig_id (przeksztalci na nazwy w left join using...) wynik i kierowca_id.
Wszystko dziala przy kodzie zamieszczonym w 1 poscie z tym ze najlepszy wynik dla wszystkich kierowcow zwraca ciagle ta sama najnizsza wartosc z calej tabeli nie zwracajac uwage na odwolanie do wyscigow. Jak zrobic by pokazywalo najnizsza wartosc dla wszystkich kierowcow poszczegolnych wyscigow.
mortus
Cały czas rozchodziło się o strukturę tabeli wyniki, której nam nigdzie nie podałeś. Teraz przynajmniej opis jest dokładniejszy i można coś kombinować:
  1. SELECT zespol_name, wyscig_name, MIN(w1.wynik) AS wynik,
  2. (SELECT MIN(w2.wynik) FROM " . DB_WYNIKI . " w2 WHERE w2.sesja_id IN (1,2,3,4) AND w2.wyscig_id = w1.wyscig_id) AS mini_wynik
  3. FROM " . DB_WYNIKI . " w1
  4. LEFT JOIN " . DB_WYSCIGI . " USING(wyscig_id)
  5. LEFT JOIN " . DB_ZESPOLY . " USING(zespol_id)
  6. WHERE sesja_id IN (1,2,3,4) AND kierowca_id = '" . $_GET['kierowca_id'] . "'
  7. GROUP BY wyscig_name

Powinno zadziałać, jeśli tylko kolumny zespol_name i wyscig_name są unikalne w "obrębie" wszystkich tabel, tzn. nie powtarzają się w dwóch tabelach.
arfer
Bingo Mortus smile.gif Dziala. Wielkie dzieki smile.gif
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.