Autor Zpráva
skeroth
Profil
Ahoj, nějak mi to dnes už nemyslí.

Vypisuji z db dvě náhodné číselné hodnoty, jejichž rozdíl musí být od -100 do 100.
Tzn. vytáhnu z db selectem dva řádky, ty mezi sebou v php odečtu a pokud je jejich rozdíl menší než -100 nebo větší než 100, tak se to musí provést znovu...

Jak na to ?

Díky
Alphard
Profil
Kromě AND v podmínce existuje funkce abs(), která vypočítá absolutní hodnotu. Řešil bych to na úrovni SQL, bude to rychlejší a míň náročné.
skeroth
Profil
Můžeš prosím uvést kod ? Já už právě zkoušel vše co umím a jsem z toho dost odvařenej. Teprve se učím :)
Alphard
Profil
Nejsem si jist, jak to udělat nejlépe. Napadlo mě tohle, ale joinovat na základě funkce není obecně moc dobrý nápad.
select t1.cislo, t2.cislo from tabulka t1 join tabulka t2 
    on abs(t1.cislo-t2.cislo) < 100 and t1.id != t2.id order by rand() limit 1
Nevím, jak hustou máte číselnou řadu, rychlejší by bylo vybrat první číslo a na jeho základě omezit výběr toho druhého. Jenže pokud se nenajde, vynutí si to opakování, které by obecněji mohlo trvat i déle.

Alternativně pomocí poddotazu
select t1.cislo, (select ... where abs(t2.cislo - t1.cislo) < 100 order by rand() limit 1) tt from tabulka t1 order by rand() limit 1
To ale bude asi spíš pomalejší, zkuste.
skeroth
Profil
Díky, vyzkouším. Číselná řada jsou jen celá čísla.
Tori
Profil
Alphard:
rychlejší by bylo vybrat první číslo a na jeho základě omezit výběr toho druhého
Anebo kdyby se rovnou poddotazem těch prvních čísel vybralo více? (= menší pravděpodobnost opakování)


Anebo předem omezit výběr čísel jen na ty, které mají nejbližšího souseda max 100 bodů vzdáleného, a z nich dvě náhodná. Ale koukám, že to je vlastně Alphardův join, přepsaný do závislého poddotazu. Zkusila jsem s 1000 záznamy v rozmezí 1 - 100k, u závislého poddotazu se u t2 čte jen index, u joinu skenuje celou tabulku (ani force key nezabralo).
select * from cisla t1
where exists (select * from cisla t2 where t1.cislo != t2.cislo and abs((t1.cislo-t2.cislo)) <= 100) 
order by rand()
limit 2

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