Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL] Pobranie maxymalnego wyniku
Forum PHP.pl > Forum > Przedszkole
Watt
Witam,

Chciałem pobrać wyniki uszeregowane rand, maxymalny i minimalny wyknik zapytaniem:
Kod
query("SELECT tag_name, tag_amount, MIN(tag_amount), MAX(tag_amount)  FROM `mybb_stcp` WHERE tag_name != '' GROUP BY RAND() LIMIT ".$amount)

Dokładniej: Skrypt pobiera 10 rekordów, w tych 10 szuka największego i pokazuje go (muszę od razu [po pierwszej petli] mieć największy wynik).

I nie wykonuje sie poprawnie - dlaczego ?
nospor
GROUP BY RAND()
nie slyszalem by mozna bylo grupowac po losowosci winksmiley.jpg
A na przyszlosc wyswietlas sobie komunikat bledu bazy to bedziesz od razu sam widzial co jest źle.
Watt
Tak, ale to nie wyrzuca błędu bazy danych, Order by nie wiedziałem jak zrobić, żeby pobrało dowolnie wybrane tagi dlatego tak kombinowałem.
zend
  1. SELECT tag_name, tag_amount, MIN(tag_amount), MAX(tag_amount) FROM `mybb_stcp` WHERE tag_name IN(
  2. SELECT `tag_name` FROM `mybb_stcp` ORDER BY RAND() LIMIT 10
  3. ) LIMIT 10


Z resztą powinieneś sobie juz poradzić smile.gif
piotrooo89
@zend Twoje zapytanie też nie jest pierwszych lotów, gdzie widziałeś taka składnie do wyświetlania losowego rekordu? ~nospor już o tym wspominał.
zend
To nie miało być GROUP tylko ORDER zagapiłem się smile.gif

  1. SELECT `quotes`.* FROM `quotes` ORDER BY RAND() LIMIT 1


No przykładem może być to zapytanie, które działa całkiem nieźle guitar.gif
Watt
Witam serdecznie, mam pytanie - zapytanie wyrzuca błąd:
Kod
MyBB has experienced an internal SQL error and cannot continue.

SQL Error:
    1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
Query:
    SELECT tag_name, tag_amount, MIN(tag_amount), MAX(tag_amount) FROM `mybb_stcp` WHERE tag_name IN( SELECT `tag_name` FROM `mybb_stcp` ORDER BY RAND() LIMIT 9999999 ) LIMIT 9999999
zend
  1. SELECT tag_name, tag_amount, MIN(tag_amount), MAX(tag_amount) FROM `mybb_stcp` WHERE tag_name IN(
  2. SELECT `tag_name` FROM `mybb_stcp` ORDER BY RAND()
  3. ) LIMIT 10


Spróbuj tak, bez limitu w wewnętrznym zapytaniu, poza tym lepiej by było szukać danych po id które było by typu int, a nie szukać po varchar'ach
Watt
Treść błędu się zmieniła:
Kod
MyBB has experienced an internal SQL error and cannot continue.

SQL Error:
    1140 - Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
Query:
    SELECT tag_name, tag_amount, MIN(tag_amount), MAX(tag_amount) FROM `mybb_stcp` WHERE tag_name IN( SELECT `tag_name` FROM `mybb_stcp` ORDER BY RAND() ) LIMIT 9999999
zend
  1. SELECT tag_name, tag_amount, MIN(tag_amount), MAX(tag_amount) FROM `mybb_stcp` WHERE tag_name IN(
  2. SELECT `tag_name` FROM `mybb_stcp` ORDER BY RAND()
  3. ) LIMIT 10 GROUP BY tag_name


Jaką wersję mysql'a masz? Coś mi na to wygląda że ta nasza zabawka nie ma ochoty pracować smile.gif Mógł byś jeszcze raz sprecyzować problem?
Watt
Witaj,

Kod
MyBB has experienced an internal SQL error and cannot continue.

SQL Error:
    1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY tag_name' at line 5
Query:
    SELECT tag_name, tag_amount, MIN(tag_amount), MAX(tag_amount) FROM `mybb_stcp` WHERE tag_name IN( SELECT `tag_name` FROM `mybb_stcp` ORDER BY RAND() ) LIMIT 10 GROUP BY tag_name


Wersja klienta MySQL: 4.1.10
zend
Chcesz największy i najmniejszy rekord? Posortowane rekordy z losowych? Czy może jeszcze coś innego?

  1. SELECT tag_name, tag_amount, MIN(tag_amount), MAX(tag_amount) FROM `mybb_stcp`

Zapytanie tego typu zwraca jeden rekord z wartością największą i najmniejszą, a nie wiem czy w tym rzecz
Watt
Postaram sie wyjaśnić na przykładzie
[Tag - tag_name] - [Ilość tagów - tag_amount]
lol - 2
lubie - 4
placki - 7
lalala - 1
hahaha - 3
forum - 6
php - 2

Zapytanie ma pobrac powiedzmy 4 losowe tagi i z nich wybrac największy i najmniejszy.
Przyklad:

lol, hahaha, forum, lubie
Najmniejszy: lol
Największy: forum
zend
No! Trzeba tak bylo odrazu smile.gif

  1. SELECT tag_name, tag_amount FROM `mybb_stcp` WHERE tag_name != '' ORDER BY tag_amount DESC RAND() LIMIT 10


Teraz największy rekord będzie na samym początku, a najmniejszy na końcu. Ale dalej nie rozumiem po co ten warunek sprawdzający czy dany tag nie jest pusty..
Watt
A da się to jakoś pomieszać - robie chmurkę tagów i to będzie średnio wyglądało jak to będzie po kolei, chciałem żeby to wyglądało jak chmurka smile.gif Szkoda troche php do tego uzywać jak możliwie da sie to zrobić via mysql?
zend
W php było by ci o niebo łatwiej

  1. $maxValue = 0;
  2. $minValue = 0;
  3. $maxRecord = null;
  4. $minRecord = null;
  5. $output = '<ul>';
  6.  
  7. while($nextRow)
  8. {
  9. if($nextRow['value'] > $maxValue)
  10. {
  11. $maxValue = $nextRow['value'];
  12. $maxRecord = $nextRow;
  13. }
  14.  
  15. if($nextRow['value'] < $minValue)
  16. {
  17. $minValue = $nextRow['value'];
  18. $minRecord = $nextRow;
  19. }
  20.  
  21. $output .= '<li>'.$nextRow['tag_name'].'</li>';
  22. }
  23.  
  24. $output .= '</ul>';


Możesz zastosować takie rozwiązanie jeżeli szkoda Ci przelecieć wyniki zapytania jeszce jedną pentlą party.gif
mortus
Cytat(zend @ 26.03.2010, 22:16:42 ) *
No! Trzeba tak bylo odrazu smile.gif
  1. SELECT tag_name, tag_amount FROM `mybb_stcp` WHERE tag_name != '' ORDER BY tag_amount DESC RAND() LIMIT 10
Teraz największy rekord będzie na samym początku, a najmniejszy na końcu. Ale dalej nie rozumiem po co ten warunek sprawdzający czy dany tag nie jest pusty..
Po pierwsze zapytanie składniowo niepoprawne (brakuje przecinka po tag_amount DESC). Po drugie zapytanie nie działa tak, jak powinno. Dlaczego? Ano dlatego, że najpierw sortuje malejąco po kolumnie tag_amount, a później to co już zostało posortowane ma posortować w sposób losowy i nie sortuje. Wynikiem zapytania zawsze będą te same rekordy, czyli 10 rekordów z całej tabeli mybb_stcp, których tag_amount jest największe.
Cytat(Watt @ 26.03.2010, 22:08:08 ) *
Postaram sie wyjaśnić na przykładzie
[Tag - tag_name] - [Ilość tagów - tag_amount]
lol - 2
lubie - 4
placki - 7
lalala - 1
hahaha - 3
forum - 6
php - 2

Zapytanie ma pobrac powiedzmy 4 losowe tagi i z nich wybrac największy i najmniejszy.
Przyklad:

lol, hahaha, forum, lubie
Najmniejszy: lol
Największy: forum
Jeśli wartość tag_amount może się powtarzać, to zapytanie, które wybiera z pośród kilku losowych rekordów rekord o największym i najmniejszym tag_amount nie ma sensu. Dlaczego? Dlatego, że może być kilka rekordów o najmniejszym lub największym tag_amount. Obrazując: załóżmy, że z przykładowych danych, które podałeś wylosowaliśmy 4 rekordy zawierające tag_name i tag_amount. Niech to będą: [hahaha - 3], [forum - 6], [lol - 2] i [php - 2]. Zauważ, że w wylosowanych rekordach mamy dwa, które mają najmniejsze tag_amount. Które zatem mamy wybrac?
Gdyby wartość tag_amount była różna dla każdego tag_name, to rozwiązaniem byłoby
  1. SELECT tag_name, tag_amount FROM mybb_stcp WHERE tag_name != '' AND (tag_amount=(SELECT MIN(tag_amount) FROM (SELECT tag_name, tag_amount FROM mybb_stpc ORDER BY RAND() LIMIT 4) AS temp) OR tag_amount=(SELECT MAX(tag_amount) FROM (SELECT tag_name, tag_amount FROM mybb_stcp ORDER BY RAND() LIMIT 4) AS temp)) ORDER BY tag_amount
przy czym pierwszy wiersz zawierałby najmniejszą wartość tag_amount, a drugi największą.
Rozwiązanie takie zadziała również dla powtarzających się wartości tag_amount, ale z losowych rekordów wybierze wszystkie, które mają tag_amount najmniejsze i wszystkie, które mają tag_amount największe.
EDIT:
Po namyśle nadal nie jestem pewien, czy powyższe zapytanie zadziała bezbłędnie. Na pewno bezbłędnie zadziała coś takiego:
  1. SELECT tag_name, tag_amount FROM (SELECT * FROM mybb_stcp WHERE tag_name != '' ORDER BY RAND() LIMIT 4) AS temp ORDER BY tag_amount
przy czym rekordy o najmniejszym tag_amount będą pierwsze (nie wiemy ile ich będzie, jeśli wartość tag_amount może się powtarzać), a rekordy o największym tag_amount będą ostatnie (i też nie wiemy ile ich będzie, jeśli wartość tag_amount może się powtarzać).
Oczywiście LIMIT dowolny (ja wpisałem 4).
Watt
Witam,wielkie dzięki za pomoc z tym, że to dalej nie działa prawidłowo - odwołałem się tak:
  1. $stcp_query = $db->query("SELECT tag_name, tag_amount FROM mybb_stcp WHERE tag_name != '' AND (tag_amount=(SELECT MIN(tag_amount) FROM (SELECT tag_name, tag_amount FROM mybb_stcp ORDER BY RAND() LIMIT 4) AS temp) OR tag_amount=(SELECT MAX(tag_amount) FROM (SELECT tag_name, tag_amount FROM mybb_stcp ORDER BY RAND() LIMIT 4) AS temp)) ORDER BY tag_amount") or die(':<');
  2. while($stcp_fetch = $db->fetch_array($stcp_query))
  3. {
  4.  
  5. $tag = $stcp_fetch['tag_name'];
  6. $tagsiz = $stcp_fetch['tag_amount'];
  7. $max_tagsize = $stcp_fetch['MAX(tag_amount)'];
  8. $min_tagsize = $stcp_fetch['MIN(tag_amount)'];
  9. echo $tag." ".$tagsiz."<br />";
  10. }

I nie zwraca mi wyników - co jest tego przyczyną?
mortus
Spróbuj dać die(mysql_error) zamiast die (':<'). Zobaczysz, czy zapytanie się wykonuje, czy wywala błąd.
EDIT:
Zapytanie testowałem i powinno działać zarówno na MySQL-u w wersji 4.1.10, jak i nowszym.
zend
@mortus - dzięki, faktycznie podałem rozwiązdanie z błędem składniowym
  1. SELECT tag_name, tag_amount FROM `mybb_stcp` WHERE tag_name != '' ORDER BY tag_amount RAND() LIMIT 10

Ale to zapytanie i ten kawałek php które podałem kilka postów wyżej powinny załatwić sprawę
piotrooo89
o wiele wydajniejszym jest przerzucenie funkcjonalności na SQL niż wykonywanie jej po stronie PHP.
mortus
I tu znowu błąd
Cytat(zend @ 27.03.2010, 11:21:40 ) *
@mortus - dzięki, faktycznie podałem rozwiązdanie z błędem składniowym
  1. SELECT tag_name, tag_amount FROM `mybb_stcp` WHERE tag_name != '' ORDER BY tag_amount RAND() LIMIT 10
Ale to zapytanie i ten kawałek php które podałem kilka postów wyżej powinny załatwić sprawę
Jeśli już, to powinno być:
  1. SELECT tag_name, tag_amount FROM `mybb_stcp` WHERE tag_name != '' ORDER BY tag_amount, RAND() LIMIT 10
Ale takie zapytanie nie załatwia problemu, ponieważ nie można sortować po konkretnych wartościach i jednocześnie losowo. W takim zapytaniu uwzględniane jest tylko sortowanie po wartościach w kolumnie tag_amount, a co za tym idzie zawsze dostaniemy dziesięć tych samych rekordów.

EDIT:
Ogólnie skłaniałbym się ku takiemu rozwiązaniu
  1. SELECT tag_name, tag_amount FROM (SELECT tag_name, tag_amount FROM mybb_stcp WHERE tag_name != '' ORDER BY RAND() LIMIT 4) AS wylosowane WHERE tag_amount=(SELECT MIN(tag_amount) FROM wylosowane) OR tag_amount=(SELECT MAX(tag_amount) FROM wylosowane)
Teoretycznie zapytanie wygląda dobrze, niestety nie jest prawidłowe i pojawia się błąd, który mówi, że tabela wylosowane nie istnieje, czyli źródło nie jest zapisywane jako alias. Poszperałem, poszukałem i niestety bug ten był zgłoszony, ale do tej pory nikt go nie poprawił. W związku z tym obawiam się, że samym zapytaniem SQL nie zrobisz dokładnie tego, co chcesz i trzeba będzie wynik przetworzyć w PHP. W związku z tym polecam
  1. SELECT tag_name, tag_amount FROM (SELECT * FROM mybb_stcp WHERE tag_name != '' ORDER BY RAND() LIMIT 4) AS temp ORDER BY tag_amount
i skrypt
  1. <?php
  2. // nawiązanie połączenia z serwerem baz danych
  3. // wybieranie bazy danych
  4. $zapytanie = "SELECT tag_name, tag_amount FROM (SELECT * FROM mybb_stcp WHERE tag_name != '' ORDER BY RAND() LIMIT 4) AS temp ORDER BY tag_amount";
  5. $wyniki = mysql_query($zapytanie);
  6. if(false !== $wyniki && mysql_num_rows() > 0) {
  7. while($wiersz = mysql_fetch_array($wyniki)) {
  8. $tagi[] = $wiersz['tag_name'];
  9. }
  10. }
  11. $najmniej = $tagi[0];
  12. $najwiecej = $tagi[(count($tagi) - 1)];
  13. ?>
Watt
Właśnie, a ja nie mogę pozwolić sobie na 'szaleństwa' z obecnym hostingiem. Dlatego właśnie napisałem tutaj 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.