Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: PHP, SQL: Suunnilleen saman rankin omaavan hakeminen

E1ss [15.10.2017 14:17:14]

#

Olen tekemässä peliä jossa kaikilla pelaajilla on rankki. Kun pelaaja painaa play nappia niin se hakee tietokannasta kaikki pelaamattomat pelit ja vaitsee sieltä itselleen lähimpänä rankkia olevan vastustajan. Tässä on kaksi ongelmaa. Ensimmäinen on se että en tiedä miten pystyn hakemaan lähellä olevan muuten kuin että käyn koko listan läpi ja katson yksitellen kenellä on yksi piste vähemmän tai enemmän ja jatkan niin pitkään kunnes joku löytyy. Toinen ongelma on se että jos pelissäni olisikin vaikka 1,000,000 pelaamatonta peliä niin kaikkien niiden hakeminen serveriltä varmasti hidastaisi sitä ja kestäisi pelaajaltakin kauan. Ajattelin että voisinko jollain sql komennolla hakea suoraan tietokannasta pelaajan joka on lähellä omaa rankia.

esim.
Oma rank: 1000

Etsii pelin jossa vastustajan rankki on mahdollisimman lähellä omaa.

Löytää pelaajan jonka rank on 1025

Jaska [15.10.2017 15:36:53]

#

Monessa tietokannassa on itseisarvon laskentaan joku ABS-funktio tai vastaava. Siten voit koettaa jotain tyyliin

SELECT TOP 1 FROM TAULU
WHERE hakuehdot
ORDER BY ABS( rankki - omarankki )

Kokeilin osoitteessa https://www.w3schools.com/sql/trymysql.asp?filename=trysql_func_mysql_abs seuraavaa onnistuneesti:

SELECT * FROM Customers WHERE ABS(postalcode - 13000) < 1000 ORDER BY ABS(postalcode - 13000)

E1ss [15.10.2017 17:50:22]

#

Sori mutta en ihan viellä ymmärtänyt. Jos minulla on esim. tietokanta jossa on nimi, salasana ja rank. Sitten katson että oma rank on 10 ja yritän etsiä mahdollisimman lähellä olevan (ylös ja alas päin) rankin.

SELECT * FROM Customers WHERE ABS(postalcode - 10) < 1000 ORDER BY ABS(postalcode - 10)

Mitä sijoitan tuon tuhannen paikalle vai menikö tämä edes oikein? Onko tuossa ideana että tuo hakee kaikki joilla rank on tuhat yli 10 tai alle 10 vai mitä se tarkoittaa?

Jaska [15.10.2017 18:11:12]

#

E1ss kirjoitti:

SELECT * FROM Customers WHERE ABS(postalcode - 10) < 1000 ORDER BY ABS(postalcode - 10)

Mitä sijoitan tuon tuhannen paikalle vai menikö tämä edes oikein? Onko tuossa ideana että tuo hakee kaikki joilla rank on tuhat yli 10 tai alle 10 vai mitä se tarkoittaa?

Tuo koodi etsii kaikki postalcodet, jotka eroavat kympistä alle tuhannella. Kannattaa kerrata itseisarvon käsite. Lauseke |a-b| < c tarkoittaa, että a:n ja b:n etäisyys lukusuoralla on alle c:n päässä toisistaan. Itseisarvoa käytetään mittaamaan juuri haluamaasi asiaa eli arvoa, joka on mahdollisimman lähellä haluamaasi rankkia.

Katsotaanpa sitten koodia

SELECT TOP 1 FROM TAULU
WHERE hakuehdot
ORDER BY ABS( rankki - omarankki )

Jos sinulla on siis rank = 10 ja kannassa vaikkapa rankit 7, 8, 9, 11, 12, 14, niin abs(rankki-omarankki) saa arvot |7-10|=3, |8-10|=2, |9-10|=1, |11-10|=1, |12-10|=2 ja |14-10|=4. Sitten erotukset järjestetään: 1, 1, 2, 2, 3, 4 ja valitaan pienin.

Tuohon kyselyyn pitäisi lisätä joku tarkastus, että ei valita itseä vastustajaksi, eli siihen pitäisi laittaa joku id-tarkastus vielä. En tiedä, miten olet kannassasi yksilöinyt eri pelaajat.

Metabolix [16.10.2017 17:01:20]

#

Käytännössä MySQL:llä kysely voisi näyttää tältä (kunhan sijoitat siihen arvot oma_id ja oma_rankki):

SELECT * FROM pelaaja
WHERE pelaaja.id != oma_id
ORDER BY ABS(pelaaja.rankki - oma_rankki) ASC
LIMIT 1

Jos haluat mukaan satunnaisuutta, voit valita kyselyllä monta riviä (vaikka LIMIT 10) ja arpoa sitten koodissa niistä.

E1ss [17.10.2017 18:11:48]

#

En tiedä miksi tämä ei toimi

$kysely = $yhteys->prepare("SELECT * FROM games WHERE id != ? ORDER BY ABS(? - ?)");
$kysely->execute(array(1, 10, 1500));

Eli haarukka on 10 ja oma rankki 1500 mutta se vain tulostaa koko listan id:n perusteella (eli 1,2,3...) läpi vaikka listalla ei ole yhtäkään sellaista joka olisi 10 päässä 1500. Mitä teen väärin?

Jaska [17.10.2017 19:39:27]

#

Koska sinun pitää järjestyskriteeriossa aina olla ABS(rankki-omarankki) eli muuttujien nimet. Yrität järjestää kriteerin ABS(10-1500)=1490 mukaan. Mutta ei kuulosta kovin järkevältä, että sinulla olisi järjestyskriteerinä joku vakio.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta