Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL] Losowy rekord
Forum PHP.pl > Forum > Bazy danych
Bartol
Wątek na ten temat założyłem już na goldenline, niestety nie otrzymałem pomocy... (http://www.goldenline.pl/forum/bazy-danych/397748)

Napiszę w skrócie o co chodzi:
Mam takie zapytanie:
  1. SELECT
  2. m.id,
  3. n.nazwa miejscowosc,
  4. o.id,
  5. o.nazwa
  6. FROM miejscowosci m LEFT JOIN miejscowosci_nazwa n ON n.m_id = m.id AND n.j_id = '1' LEFT JOIN obiekty o ON o.miejscowosc = m.id
  7. GROUP BY m.id;


Chce z kazdej miejscowosci wyciagnac losowy obiekt. Nazwy miejscowosci przechowywane sa w drugiej tabeli (miejscowosci_nazwa) ze wzgledu na rozne nazewnictwo przy roznych wersjach jezykowych.

Problem polega na tym, ze nie wyciaga mi losowego obiektu, tylko zawsze pierwszy, ktory jest dodany do danej miejscowosci.

Podaje też kilka innych tasiemców, których próbowałem...:
  1. SELECT m.id, n.nazwa miejscowosc, o.id, o.nazwa
  2. FROM miejscowosci m
  3. LEFT JOIN miejscowosci_nazwa n ON n.m_id = m.id AND n.j_id = '1'
  4. LEFT JOIN obiekty o ON o.miejscowosc = m.id AND o.id = (
  5. SELECT id
  6. FROM obiekty WHERE miejscowosc = m.id
  7. ORDER BY RAND( )
  8. LIMIT 1 )
  9. GROUP BY m.id;


Działa prawie dobrze. Zwraca losowe obiekty przypisane do każdej miejscowości, ale czasami zamiast obiektu zwraca null...

Kolejny tasiemiec do kolekcji:
  1. SELECT
  2. n.nazwa,
  3. m.id,
  4. o.id,
  5. o.nazwa
  6. FROM miejscowosci m LEFT JOIN miejscowosci_nazwa n ON n.m_id = m.id AND n.j_id = '1', obiekty o
  7. WHERE o.id = (SELECT id FROM obiekty WHERE miejscowosc = m.id ORDER BY RAND() LIMIT 1 )
  8. GROUP BY
  9. m.id


Tym razem albo zwraca miejscowosc z losowym obiektem z tej miejscowosci, albo w ogole nie zwraca miejscowosci (pewnie to przez WHERE)
wipo
Jak nie chcesz mieć null to dołączaj tabele samym join (left join połączy tablice nawet jak warunek połączenia nie jest spełniony)
Bartol
Cytat(wipo @ 22.06.2008, 16:48:23 ) *
Jak nie chcesz mieć null to dołączaj tabele samym join (left join połączy tablice nawet jak warunek połączenia nie jest spełniony)

Przy samym JOIN efekt jest identyczny...
wipo
  1. SELECT m.id, n.nazwa miejscowosc, o.id, o.nazwa
  2. FROM miejscowosci m
  3. LEFT JOIN miejscowosci_nazwa n ON n.m_id = m.id AND n.j_id = '1'
  4. LEFT JOIN obiekty o ON o.miejscowosc = m.id AND o.id = (
  5. SELECT id
  6. FROM obiekty WHERE miejscowosc = m.id
  7. ORDER BY RAND( )
  8. LIMIT 1 ) WHERE o.nazwa NOT NULL
  9. GROUP BY m.id;


pozatym zobacz czy w tablicach z obiektami nie masz przypadkiem jakiegos nulla
Bartol
Cytat(wipo @ 23.06.2008, 04:37:36 ) *
  1. SELECT m.id, n.nazwa miejscowosc, o.id, o.nazwa
  2. FROM miejscowosci m
  3. LEFT JOIN miejscowosci_nazwa n ON n.m_id = m.id AND n.j_id = '1'
  4. LEFT JOIN obiekty o ON o.miejscowosc = m.id AND o.id = (
  5. SELECT id
  6. FROM obiekty WHERE miejscowosc = m.id
  7. ORDER BY RAND( )
  8. LIMIT 1 ) WHERE o.nazwa NOT NULL
  9. GROUP BY m.id;


pozatym zobacz czy w tablicach z obiektami nie masz przypadkiem jakiegos nulla

Nie ma żadnego nulla na pewno, są tylko testowe dane, dosłownie kilka rekordów.

Twój przykład działa podobnie jak jeden z moich. Poniżej wynik działania dla kilku odświeżeń:
Cytat
id miejscowosc id nazwa
1 Zakopane 1 u antka
2 Testowa 3 dupaaa1

id miejscowosc id nazwa
2 Testowa 3 dupaaa1

id miejscowosc id nazwa
1 Zakopane 2 u zdzicha

NULL

id miejscowosc id nazwa
1 Zakopane 1 u antka
2 Testowa 4 dupa2


Przypisania obiektów do miejscowości i ich losowość są w porządku. Problem polega na tym, że czasami opuszcza miejscowość/ci nie wiadomo czemu i nie uwzględnia ich w ogóle w wynikach.
wipo
jestes pewnien ze to jest prawidlowe?
  1. LEFT JOIN obiekty o ON o.miejscowosc = m.id AND

w warunku porównujesz stringa z liczbami
po drugie jak nie znajduje miejscowosci (daje null) to moze dodaj
  1. WHERE n.nazwa miejscowosci NOT NULL
Bartol
Cytat(wipo @ 23.06.2008, 09:55:30 ) *
jestes pewnien ze to jest prawidlowe?
  1. LEFT JOIN obiekty o ON o.miejscowosc = m.id AND

w warunku porównujesz stringa z liczbami

Jestem pewien. o.miejscowosc jest typu int.
Cytat(wipo @ 23.06.2008, 09:55:30 ) *
po drugie jak nie znajduje miejscowosci (daje null) to moze dodaj
  1. WHERE n.nazwa miejscowosci NOT NULL

zaraz poprobuje
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.