Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MYSQL] Problem z unikalnymi danymi
Forum PHP.pl > Forum > Przedszkole
pozik
Mam tabelę pracownicy(jest to jedyna tabela w bazie), w której mam następujące kolumny: imie, nazwisko, wyplata

Potrzebuje zrobić zapytanie, które wypisze unikalne (imię i nazwisko) i dla tych unikalnych danych tylko najwyższą wypłata.

Ma ktoś pomysł jak to zrobić?

Próbowałem w ten sposób: SELECT DISTINCT imie, naziwsko FROM pracownicy
Nie wiem jak dołączyć do tego najwyższą wypłatę.
ssstrz
  1. SELECT DISTINCT imie, nazwisko FROM pracownicy ORDER BY wyplata
mortus
Przy takiej budowie tabeli, jaką opisałeś (swoją drogą całkowicie niepoprawną) powinno zadziałać to
  1. SELECT `p`.`imie`, `p`.`nazwisko`, MAX(`p`.`wyplata`) `najwieksza_wyplata` FROM `pracownicy` `p` GROUP BY `p`.`imie`, `p`.`nazwisko`
Michasko
  1. WHERE wyplata = max(wyplata)
pozik
Cytat(mortus @ 24.04.2013, 20:21:15 ) *
Przy takiej budowie tabeli, jaką opisałeś (swoją drogą całkowicie niepoprawną) powinno zadziałać to
  1. SELECT `p`.`imie`, `p`.`nazwisko`, MAX(`p`.`wyplata`) `najwieksza_wyplata` FROM `pracownicy` `p` GROUP BY `p`.`imie`, `p`.`nazwisko`

Zadziałało, dzięki! Dlaczego niepoprawną?

Mam jeszcze jedno pytanie. Teraz chciałbym zliczyć najwyższe wypłaty większe od $getwyplata. Zrobiłem zapytanie:
$query = "SELECT imie, nazwisko, MAX(wyplata) AS 'maxwyplata' FROM pracownicy GROUP BY imie, nazwisko WHERE maxwyplata > $getwyplata";
$result = mysql_query($query);
... i dalej nie wiem...

Jest możliwość wrzucenia jakiegoś globalnego COUNT() tutaj?
matiit
Zamiast WHERE daj HAVING
pozik
Pomogłeś! Dziękuję!

Zrobiłem coś takiego:
  1. (...)
  2. $query = "SELECT imie, nazwisko, MAX(wyplata) AS 'maxwyplata' FROM pracownicy GROUP BY imie, nazwisko HAVING maxwyplata > $getwyplata";
  3. $result = mysql_query($query);
  4. $num = mysql_numrows($result);
  5.  
  6. echo ("$num");
  7. (...)
matiit
Jest spoko, tylko pamiętaj o SQL injection smile.gif
pozik
Zabezpieczyłem w taki sposób:

$getwyplata = str_replace("<", "", $getwyplata);
$getwyplata = str_replace(">", "", $getwyplata);
$getwyplata = str_replace("!", "", $getwyplata);
$getwyplata = str_replace("/", "", $getwyplata);
$getwyplata = str_replace("\", "", $getwyplata);

Wystarczy?
matiit
Nie, bo co jak $getwyplata będzie np. "10; DROP TABLE pracownicy;" ?
Ale fajnie, że kombinujesz i próbujesz.
Polecam Ci po prostu poczytać o SQL injection, jest tego masa na necie.
Ale idziesz w dobrym kierunku, gratulujęsmile.gif
mmmmmmm
Wystarczy proste intval()... I o SQL-injection możesz zapomnieć.
pozik
Poszukam i poczytam dzięki matiit smile.gif Dzieki mmmmmmm za pokazanie jak zabezpieczyć przekazywanie wartości smile.gif Teraz jeszcze poszukam jak skutecznie zabezpieczyć stringa smile.gif
matiit
Kolega wyżej ma rację. Wtrące jeszcze tylko swoje 0.03PLN - lepiej użyć (int) $zmienna niż intval($zmienna) z powodów optymalizacyjnych.
Tutaj "benchmark"
http://hakre.wordpress.com/2010/05/13/php-casting-vs-intval/
pozik
Nigdy nie zdawałem sobie sprawy z tego, że włamanie się do bazy może być tak łatwe. Udało mi się przeprowadzić atak na mojej bazie. Teraz już zabezpieczyłem trochę. Pomogliście mi. Co do zabezpieczania stringów, to znalazłem: $imie = mysql_escape_string($imie);
pmir13
Skoro już znalazłeś taką funkcję to mam nadzieję, że przeczytałeś do niej manual, gdzie w wielkim czerwonym oknie na samej górze napisane jest, że już w tej chwili wszystkie funkcje z mysql_ są przestarzałe, a w przyszłych wersjach będą w ogóle usunięte.
W zasadzie nie rozumiem dlaczego dyskutujecie na temat jak zabezpieczyć kod typu mysql_ zamiast dyskutować o tym że w ogóle nie należy go stosować. Serio, PDO nie jest takie straszne jak się wydaje, a parametryzowane wywołania zupełnie eliminują problem SQL injection. Wciąż trzeba uważać na XSS jeśli wypluwamy na stronę jakikolwiek html z bazy, ale to i tak duży postęp w stosunku do tego na co trzeba uważać z mysql_.
pozik
Nie zwróciłem uwagi na taką informację. Wychodzi na to, że nadal muszę szukać rozwiązania...
pmir13
  1. $dbh = new PDO( ... );
  2. ...
  3. $query = "SELECT imie, nazwisko, MAX(wyplata) AS 'maxwyplata' FROM pracownicy GROUP BY imie, nazwisko HAVING maxwyplata > :getwyplata";
  4. $stmt = $dbh->prepare( $query );
  5. $stmt->bindParam( ':getwyplata', $getwyplata, PDO::PARAM_INT );
  6. $stmt->execute();


Szymciosek
Cytat(pmir13 @ 25.04.2013, 00:14:33 ) *
Skoro już znalazłeś taką funkcję to mam nadzieję, że przeczytałeś do niej manual, gdzie w wielkim czerwonym oknie na samej górze napisane jest, że już w tej chwili wszystkie funkcje z mysql_ są przestarzałe, a w przyszłych wersjach będą w ogóle usunięte.
W zasadzie nie rozumiem dlaczego dyskutujecie na temat jak zabezpieczyć kod typu mysql_ zamiast dyskutować o tym że w ogóle nie należy go stosować. Serio, PDO nie jest takie straszne jak się wydaje, a parametryzowane wywołania zupełnie eliminują problem SQL injection. Wciąż trzeba uważać na XSS jeśli wypluwamy na stronę jakikolwiek html z bazy, ale to i tak duży postęp w stosunku do tego na co trzeba uważać z mysql_.



Możesz coś więcej powiedzieć o XSS? Jak to ma się do trzymania w bazie kodu html i wyświetlania go np. przy korzystania z klasy View, która pobiera i wyświetla html z bazy?
pmir13
W XSS w bardzo dużym skrócie chodzi o to, że jeśli użytkownik ma możliwość wprowadzenia do bazy gdziekolwiek jakiegokolwiek tekstu, z którego potem będzie składany html, to może próbować wstawić coś, co uruchomi javascript, którego źródło może być gdzieś na zewnętrznym serwerze. Przykłady tego, co można próbować wstawić do bazy można znaleźć tutaj: https://www.owasp.org/index.php/XSS_Filter_...ion_Cheat_Sheet.
Jeśli chodzi o widoki to wszystko zależy od tego jak są napisane, każdy przypadek jest inny, na pewno bezpieczny jest tylko taki html z bazy, na który użytkownik odwiedzający stronę nie ma wpływu.
mmmmmmm
Sorry, ale większego szajsu niż PDO to dawno nie spotkałem...
Programuję długo (ponad 20 lat) w wielu językach. W PHP jakieś 5-6 lat. Zawsze używałem mysql_ jako najszybsze. Ostatnio próbowałem PDO. Takich problemów, jak z PDO to dawno nie miałem... Każda następna będzie na pewno z użyciem mysqli_
Aby nie być gołosłownym:
1. UPDATE `tabela` SET `pole='wartość' WHERE `id`=1
Brak błędu - zarówno w PDOException, jak i errorInfo().
2. Nie zgłasza błędów w momencie nie dodania rekordów z powodu np. złego triggera.
3. rowCount() nie daje wyników dla SELECT (to akurat jest opisane w dokumentacji) - porażka.
matiit
pmir13
Wg mnie i tak warto znać podstawy zabezpieczeń, a i trochę "historii" jak to było parę lat temu też nikomu nie zaszkodzi.
Czy się przydać może to w praktyce? Oczywiście. Miałem ostatnio klienta, który miał serwis na serwerze bez możliwości włączenia PDO czy mysqli, miałem dorobić trochę funkcjonalności i trzeba było się w tym babrać, cóż poradzić.
A przy okazji dopisują swój kod nie mogłem pozwolić na to, aby był podatny na ataki - więc musiałem wiedzieć jakie są podstawowe zagrożenia przy używaniu mysql_*
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.