Autor Zpráva
Kalby
Profil
Zdravím,

nevím si teď rady s jedním SQL dotazem. Přemýšlím, jak by se to dalo vyřešit pouze jedním SQL dotazem, ale zatím mě nic nenapadlo:

Mám tabulku se seznamem lokalit.

ID, Nazev lokality

Dále mám tabulku se seznamem objektu

ID, nazev, poradi, ID_lokality


Nyní potřebuji vybrat všechny lokality v náhodném pořadí (pokaždé jiné pořadí). Z každé lokality vybrat pouze jeden objekt. Objekt se vybere podle sloupce pořadí. Ale tak, ze pokud pro danou lokalitu neni uprednostnen zadny objekt (poradi 999) vybere se nejaky nahodny. Pokud jsou nejake objekty s poradim mensim nez 999, vybere se ten s nejnizsim poradim.

Zatím mám toto:

SELECT o.nazev_objektu_cz,o.id,o.url,l.lok_nazev_cz,o.typ_ubytovani 
                                from lokality as l
                                join objekt as o on o.lokalita_id=l.id  and o.aktivni=1
                                where l.online=1
                                GROUP BY l.id  


Bohužel pokud vložím GROUP BY nemůžu už řadit objekty tak jak bych chtěl. Náhodné řazení lokalit by šlo udělat až v php, to už není podmínkou, ale nedaří se mi ani to řazení objektů

je mi jasne ze pokud by tam nebylo GROUP by mohu nastavit ORDER by o.poradi ASC, RAND(), ale takto to nejde.
Joker
Profil
Kalby:
Objekt se vybere podle sloupce pořadí. Ale tak, ze pokud pro danou lokalitu neni uprednostnen zadny objekt (poradi 999) vybere se nejaky nahodny. Pokud jsou nejake objekty s poradim mensim nez 999, vybere se ten s nejnizsim poradim.
Tohle by snad šlo:
ORDER BY IF(poradi=999, poradi + RAND(), poradi)
…ale ty objekty by to asi chtělo udělat poddotazem a následně ty lokality.
Kajman_
Profil *
Asi to nebude nejrychlejší, ale mohlo by jít něco jako

select ob.*, t.*
from   (select l.lok_nazev_cz,
               (select o.id
                from   objekt o
                where  o.lokalita_id = l.id
                       and o.aktivni = 1
                order  by poradi, rand()
                limit  1) obid
        from   lokality as l
        where  l.online = 1) t
join   objekt ob
on     ob.id = t.obid


Případné omezení lokalit (např. limitem v podotaze t) by se hodilo, aby to nebylo tak moc pomalé.
Kalby
Profil
Omezení se neplánuje lokalit je do 50. Ten dotaz je teda docela pomaly, ale s tím se dalo počítat. Asi ho stejně nacachuju, takže snad nebude problém. Kajmanovo řešení funguje.

Díky za pomoc
Kajman_
Profil *
Tak 50 je fajn. Když bude složený index např. (aktivni,lokalita_id,poradi), třeba to svižnější.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0