Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: PHP, MySQL: Tietojen lajittelu eri otsikoiden alle

Sivun loppuun

merlin [18.10.2013 10:09:15]

#

Nyt olisi tarkoitus tulostaa hevosten nimiä tietokannasta ja järjestää ne eri väliotsikoiden alle sen mukaan, minkä korkuisia esteitä ne hyppäävät. Hyppytaso on siis muuttuja $taso ja se vastaa tietokannan saraketta estekorkeus. Hevosen nimi löytyy tietokannasta kohdasta nimi. Tällainen pätkä olisi tarkoitus tulostaa jokaiselle estekorkeudelle jolta hevosia löytyy. Eli siis kolme soluiseen taulukkoon. Ilmeisesti jotain silmukoita tarvittaisiin, mutta mun aivot ei kyllä yhtään tajunnut että miten pitäisi alottaa kun putkan oppaita silmukoista lueskelin.

- haetaan kannasta nimi ja este
- tulostus kolmesoluiseen taulukkoon, jokaiselle tasolle, josta hevonen löytyy, oma solu -> näin ollen rivitys pitäisi saada siis toimimaan joka kolmannen solun välein
- niille tasoille ei tulosteta omaa solua eikä otsikoa, jolta ei hevosia löydy
- tasoja ovat esim. 100cm, 110cm jne. Ovat tietokannassa tekstimuodossa.

<table class="perustiedot">
<tr><td class="vastaava" width="33%">
<h3><?php echo $taso; ?></h3>

<?php
// valmistetaan kysely
$kysely = $yhteys->prepare("SELECT nimi, estekorkeus FROM hevoset WHERE talli='ratsu' AND kaytto='kisa' AND estekorkeus=? ORDER BY nimi");
// suoritetaan kysely
$kysely->execute(array($taso));

// n&auml;ytet&auml;&auml;n kyselyn tulokset taulukossa

// k&auml;sitell&auml;&auml;n tulostaulun rivit yksi kerrallaan
while ($rivi = $kysely->fetch()) {

echo $rivi["nimi"] . "<br />" ;

}
?></p></td>
</table>

Lebe80 [18.10.2013 10:45:51]

#

Eikö noita tulostaa vain kaikkia ilman tuota "estekorkeus"-ehtoa, ja järjestää vain ensin estekorkeuden mukaan pienimmästä isoimpaan, ja sitten vasta nimen.

Php:lla vain tulostat väliotsikon aina kun estekorkeus muuttuu.

Muuten en oikein tajua mikä sun ongelmasi edes on...

edit:
Eikö sulla ole vähän tablen väärinkäyttöä, jos et tulosta tuota sun listaasi edes erillisiin soluihin, vaan tunget ne kaikki yhteen isoon soluun?

merlin [18.10.2013 11:02:53]

#

Lebe80, kun se ongelma on se väliotsikon tulostus sinne oikeisiin väleihin :D Olisi pitänyt sekin mainita, että se riittää myös - tosin sitten vielä ongelmaksi jää tuo soluihin jakaminen ja rivitys.

En ole laittamassa kaikkia samaan soluun, vaan:

<tr>
<td>korkeus 1</td>
<td>korkeus 2</td>
<td>korkeus 3</td>
</tr>
<tr>
<td>korkeus 4</td>
<td>korkeus 5</td>
<td>korkeus 6</td>
</tr>

Lebe80 [18.10.2013 11:25:55]

#

Niin, niin mikset siis hae vain kaikkia koneja, ja järjestä listaa tuon estekorkeuden mukaan(?), joka viestin perusteella olisi se, joka tulostetaan aina kun estekorkeus muuttuu hevosien välillä.

Eli tuloksena tulisi kaiketikin

heponen , estekorkeus, ..

koni 54, 100
koni 55, 100
koni 59, 100
koni 65, 100
koni 1, 110
koni 45, 110
koni 47, 110
koni 3, 120
koni 6, 120
...

Näistä sitten tulostat luupissasi estekorkeuden otsikoksi, aina kun se muuttuu.

Tämä kaiketikin oli se asia jota haetaan (?)


edit:
Teeppäs joku ihan valmis käsin väännetty esimerkki, vaikka kuvana tai html-sivuna, mikä pitäisi olla lopputulos, niin tuon miettiminen olisi oikeasti selkeämpää.

Metabolix [18.10.2013 12:43:17]

#

Kokeillaan nyt arvailua vielä. Pidä muistissa vanha väliotsikko, tarkista joka kierroksella, onko uusi väliotsikko erilainen, ja jos se on erilainen, se pitää tulostaa.

$vanha_valiotsikko = null;
foreach ($rivit as $rivi) {
	$valiotsikko = htmlspecialchars($rivi["foo"]);
	if ($valiotsikko !== $vanha_valiotsikko) {
		echo $valiotsikko;
		$vanha_valiotsikko = $valiotsikko;
	}
	$tieto = htmlspecialchars($rivi["bar"]);
	echo $tieto;
}

merlin [18.10.2013 13:49:01]

#

Lebe80, tämmöistä taulukkoa siis haen, kolme solua rivillä ja soluissa tietyn tason hevoset

Metabolix, mulla ei varmaan mun tietokantahaku ja tuo sun koodis diggaa toisistaan, kun heitän tämän sivuille niin ei tapahtu yhtään mitään, ei edes erroria?

<?php
$kysely = $yhteys->prepare("SELECT nimi, este, rekisterinumero FROM hevoset WHERE talli='ratsu' AND kaytto='kisa' ORDER BY este, nimi");
// suoritetaan kysely
$kysely->execute(array());

// n&auml;ytet&auml;&auml;n kyselyn tulokset taulukossa

// k&auml;sitell&auml;&auml;n tulostaulun rivit yksi kerrallaan

$vanha_valiotsikko = null;
foreach ($kysely as $tulokset) {
	$valiotsikko = htmlspecialchars($rivi["este"]);
	if ($valiotsikko !== $vanha_valiotsikko) {
		echo "<h3>" . $valiotsikko . "</h3>";
		$vanha_valiotsikko = $valiotsikko;
	}
	$tieto = htmlspecialchars($rivi["nimi"]);
	echo $tieto . "<br />";

}
?>

pistemies [18.10.2013 14:23:09]

#

merlin kirjoitti:

mulla ei varmaan mun tietokantahaku ja tuo sun koodis diggaa toisistaan, kun heitän tämän sivuille niin ei tapahtu yhtään mitään, ei edes erroria?

Mites olis pikku lisäys tuohon kohtaan:

<?php
$kysely->execute(array());
$taulussa = $kysely->fetchAll();
foreach ($taulussa as $tulokset) {
// tee se itse - toiminto?
}
?>

Metabolix [18.10.2013 14:55:36]

#

merlin kirjoitti:

Metabolix, mulla ei varmaan mun tietokantahaku ja tuo sun koodis diggaa toisistaan, kun heitän tämän sivuille niin ei tapahtu yhtään mitään, ei edes erroria?

foreach ($kysely as $tulokset) {
	$valiotsikko = htmlspecialchars($rivi["este"]);

Käytät väärää muuttujaa. Olen täysin varma, että tästä tulee PHP:ltä huomautus, jos vain laitat ne käyttöön.

Tietenkin jos todella ei tapahdu yhtään mitään (ei tulostu edes tyhjiä elementtejä), vian täytyy olla siinä, että tietokannasta ei tule yhtään riviä.

pistemies kirjoitti:

Mites olis pikku lisäys tuohon kohtaan: – – $kysely->fetchAll()

Suoritetun kyselyn (PDOStatement) voi syöttää myös suoraan foreach-silmukalle.

pistemies [18.10.2013 15:22:23]

#

Metabolix kirjoitti:

Suoritetun kyselyn (PDOStatement) voi syöttää myös suoraan foreach-silmukalle.

Joo. Oletin, että ketjun aloittaja käyttää tätä.

Metabolix kirjoitti:

Käytät väärää muuttujaa. Olen täysin varma, että tästä tulee PHP:ltä huomautus, jos vain laitat ne käyttöön.

Kannattaa sallia virheilmoitukset. Itse annan php:n tarkistaa, onko muuttujaa olemassa ja onko taulukon kenttä(index) oikein.

Metabolix [18.10.2013 15:25:21]

#

pistemies kirjoitti:

Metabolix kirjoitti:

Suoritetun kyselyn (PDOStatement) voi syöttää myös suoraan foreach-silmukalle.

Joo. Oletin, että ketjun aloittaja käyttää [PDO-luokkaa].

Niin selvästi käyttää, ja luepa nyt itse tuosta dokumentaatiosta, mitä prepare-metodi silloin palauttaa.

pistemies [18.10.2013 16:01:19]

#

Metabolix kirjoitti:

Niin selvästi käyttää, ja luepa nyt itse tuosta dokumentaatiosta, mitä prepare-metodi silloin palauttaa.

Jostakin syystä kuitenkin tämä simppeli testi

<pre>
<?php
 $dbh = new PDO('mysql:host=localhost;dbname='.$database,$user,$pass);
 $result = $dbh->prepare("SELECT * FROM taulu");
 $result->execute();
print_r($result);
?>
</pre>

palauttaa minulla pelkästään näin:

PDOStatement Object
(
    [queryString] => SELECT * FROM taulu
)

samip [18.10.2013 16:11:42]

#

print_r($result->fetchAll(PDO::FETCH_ASSOC));

merlin [18.10.2013 16:41:01]

#

En pysy teidän keskusteluissa enää mukana, mutta sen verran itse onnistuin koodia sörkkimään, että se jotain alkoi tulostaa! Nyt se kyllä tulostaa kaiken mitä kannasta löytyy, mutta jos esim. 140cm korkeita esteitä hyppääviä hevosia on useampi niin se ei laita niitä saman otsikon alle vaan tekee jokaiselle oman väliotsikon: '140cm'

<?php
$kysely = $yhteys->prepare("SELECT nimi, este, rekisterinumero FROM hevoset WHERE talli='ratsu' AND kaytto='kisa' AND este like '%cm' ORDER BY este, nimi");
// suoritetaan kysely
$kysely->execute(array());

while ($rivi = $kysely->fetch()) {
$vanha_valiotsikko = null;
	$valiotsikko = htmlspecialchars($rivi["este"]);
	if ($valiotsikko !== $vanha_valiotsikko) {
		echo "<h3>" . $valiotsikko . "</h3>";
		$vanha_valiotsikko = $valiotsikko;
	}

	$tieto = htmlspecialchars($rivi["nimi"]);
	echo $tieto . "<br />";

}
?>

Othnos [18.10.2013 16:51:43]

#

Rivin $vanha_valiotsikko = null; tulisi olla silmukan ulkopuolella, ennen silmukkaa. Nykyisessä koodissa heität silmukan joka kierroksen alussa vanhan väliotsikon menemään minkä takia ehto $valiotsikko !== $vanha_valiotsikko on aina tosi ja väliotsikko tulostetaan joka kierroksella.

Metabolix [18.10.2013 16:56:14]

#

merlin kirjoitti:

En pysy teidän keskusteluissa enää mukana,

Ei kai nyt kovin ihmeellistä mukana pysymistä vaadi, että luet kohdan ”käytät väärää muuttujaa” ja tarkistat sitä edeltävästä koodista, mitä muuttujia siinä esiintyy. Yritin siis vihjata, että foreach-silmukassasi oli muuttuja $tulokset mutta yritit silti lukea arvoa olemattomasta muuttujasta $rivi.

pistemies kirjoitti:

Metabolix kirjoitti:

Niin selvästi käyttää, ja luepa nyt itse tuosta dokumentaatiosta, mitä prepare-metodi silloin palauttaa.

Jostakin syystä kuitenkin tämä simppeli testi – – print_r($result); – –

Entä sitten? Siitä huolimatta olion voi syöttää foreachille. Ehkä sinun pitäisi tutustua mm. generaattoreihin ja iteraattoreihin. Kummatkaan eivät liity aivan täsmälleen tähän tapaukseen, mutta molemmissa on vastaava tilanne: print_r tulostaa jotain yksinkertaista mutta foreach käy läpi useita arvoja. Yleensäkään ei ehkä kannata testata asiaa A, jos haluaa tietää, toimiiko asia B.

pistemies [18.10.2013 17:20:15]

#

Metabolix kirjoitti:

print_r tulostaa jotain yksinkertaista mutta foreach käy läpi useita arvoja.

Ihan hyvä tietää. Itse käytän usein print_r funktiolla tulostettavien tietojen "esikatselua" ja kirjoittelen siitä tulostuskoodiin taulukon avaimet, joista tieto löytyy. Tuota pelkkää preparesta tulostusta ei sen takia ole tullut käytettyä eikä toimivuutta tutkittua.

Metabolix [18.10.2013 20:02:42]

#

pistemies kirjoitti:

Itse käytän usein print_r funktiolla tulostettavien tietojen "esikatselua" ja kirjoittelen siitä tulostuskoodiin taulukon avaimet, joista tieto löytyy.

Kuulostaa kyllä todella omituiselta tavalta. Etkö todella tiedä, mitä sarakkeita tauluissasi on? Ethän kai muuttujiakaan etsi kirjoittamalla print_r(get_defined_vars()), vaan tiedät valmiiksi, mitä muuttujia koodissa on.

PHP:ssä on kuitenkin myös funktio iterator_to_array, jolla saa tällaiset iteroitavat oliot muutettua taulukoiksi vaikka debuggausta varten.

pistemies [18.10.2013 21:00:24]

#

Metabolix kirjoitti:

Kuulostaa kyllä todella omituiselta tavalta. Etkö todella tiedä, mitä sarakkeita tauluissasi on?

Mikäs siinä niin omituista on? Kyllähän se helpompi on katsoa sarakkeiden nimet tuolla tavoin kuin tutkia taulun rakennetta phpmyadminilla. Mitä tulee muutoin sarakkeiden nimien tietämiseen, niin se ei riitä. Ne pitää myös pystyä muistamaan.
Samat taulut ovat tietokannassa usein vuosikausia. Pitäisikö niiden sarakkeet pystyä muistamaan nimeltä koko sen ajan kun ne siellä ovat....

merlin [18.10.2013 22:55:43]

#

Nyt toimii siltä osin, että tulostaa oikeat hepat oikeiden estekorkeuksien alle. Mahtaisiko joku osata vielä auttaa taulukko muotoon pistämisessä :D?

Metabolix [18.10.2013 22:58:18]

#

Mitähän siinä nyt on taulukkomuotoon laitettavana? Lisäät vain tr-tagit rivien alkuun ja loppuun ja td-tagit solujen ympärille.

merlin [18.10.2013 23:00:30]

#

Metabolix, rivitys on se ongelma :D esimerkki
edit// mää nyt kikkailin ongelman pois muilla tavoin, rivitykselle ei siis enää tarvetta :)

++ vielä pikku pähkinä: miten saan muutettua estekorkeuksien esiintymisjärjestystä. Nyt ne menee 110cm, 120cm, 130cm, 60cm, 80cm tietysti aakkosellisesti järjestettynä. Kun pitäisi mennä 60cm, 80c, 110cm....>
Ja ei, en halua muuttaa este -kohtaa INT:iksi, sillä sama pitäisi saada toimimaan myös muilla lajeilla ja ominaisuuksilla, joissa "tasoa" ei voi ilmaista numeraalisesti.

pistemies [19.10.2013 13:47:59]

#

Voisiko ratkaisu olla se, että järjestät nuo tulokset ensin siten, että kunkin aidan korkeus on arrayn avaimena. Kukin löytynyt heppa laitetaan omaan arrayhyn sen avaimen mukaisesti. Arrayn voi järjestää sitten vaikka tähän tapaan.

<?php
  $arr = array("120cm"=>array("hepo","katti"),
               "80cm"=>array("heponen"),
               "110cm"=>array("tamma"),
               "90cm"=>array("ori"));
  $sort = array_keys($arr);
  natcasesort($sort);
?>

Sitten tulostetaan $arr-array käyttäen apuna $sort-arrayn aakkojärjestystä.

Othnos [19.10.2013 14:15:08]

#

Jos sql:n puolella haluaa oikean järjestyksen niin kävisikö tämä?

SELECT ... ORDER BY CAST(este AS SIGNED), nimi

The Alchemist [19.10.2013 14:58:49]

#

Kokeile?

merlin [20.10.2013 10:24:35]

#

Othnosin castilla toimi noihin senttimetriluokkiin. Nyt vaan se ongelma tulee taas eteen kun kouluratsastushepat pitäisi laittaa luokkajärjestykseen ja niitä luokkia ei millään aakkosellisella säännöllä voi järjestää :D Kun järjestyksen pitäisi olla:
Helppo C
Helppo B
Helppo A
Vaativa B
Vaativa A
Prix St. George
Intermediate I
Intermediate II
Grand Prix

Miten siis saisin itse järjestyksen päätettyä :)?

Sami [20.10.2013 11:31:16]

#

Tee toinen taulu jossa kerrot järjestyksen.

TAULU HEPPA

id  nimi   luokka_id
--------------------
1   Hepo   3
2   Katti  7
3   Matti  2
4	Teppo  2
5	Joulu  7
6	Pukki  1
TAULU LUOKKA

id  nimi              jarjestys
-------------------------------
1   Helppo B          2
2   Grand Prix        9
3   Vaativa A         5
4   Prix St. George   6
5   Intermediate I    7
6   Helppo A          3
7   Intermediate II   8
8   Vaativa B         4
9   Helppo C          1

Ja sitten kyselyn voi tehdä liitoksella näin:

SELECT heppa.nimi, luokka.nimi
FROM heppa
INNER JOIN luokka ON heppa.luokka_id = luokka.id
ORDER BY luokka.jarjestys ASC, heppa.nimi ASC

merlin [20.10.2013 13:00:26]

#

Sami, kiitokset! Tällä tavalla tämä varmaan tulee onnistumaan, mutta joku mulla mättää. Mulla on siis:
taulu: hevoset
- nimi
- koulu (=koulutaso.luokka)
- rekisterinumero

taulu: koulutaso
- id
- luokka (=hevoset.koulu)
- jarjestys

$kysely = $yhteys->prepare("
SELECT hevoset.nimi, hevoset.koulu, hevoset.rekisterinumero , koulutaso.luokka, koulutaso.jarjestys
FROM hevoset
WHERE hevoset.talli='ratsu' AND hevoset.kaytto='kisa' AND hevoset.koulu<>''
INNER JOIN koulutaso
ON hevoset.koulu=koulutaso.luokka
ORDER BY koulutaso.jarjestys ASC");
// suoritetaan kysely


$kysely->execute(array());

$vanha_valiotsikko = null;

while ($rivi = $kysely->fetch()) {
	$valiotsikko = htmlspecialchars($rivi["hevoset.koulu"]);
	if ($valiotsikko !== $vanha_valiotsikko) {
		echo "<br /><b>" . $valiotsikko . "</b><br />";
		$vanha_valiotsikko = $valiotsikko;
	}

	$tieto = htmlspecialchars($rivi["hevoset.nimi"]);
	$reknumb = htmlspecialchars($rivi["hevoset.rekisterinumero"]);
	echo "Hirnaus (VRL-11675) - " . $tieto . " " . $reknumb . "<br />";

}

Pukkaa erroria:
"Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 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 'INNER JOIN koulutaso ON hevoset.koulu=koulutaso.luokka ORDER BY koulutaso.jarj' at line 4' in /home/thefakep/public_html/waldorff/g/horses.php:167 Stack trace: #0 /home/thefakep/public_html/waldorff/g/horses.php­(167): PDOStatement->execute(Array) #1 {main} thrown in /home/thefakep/public_html/waldorff/g/horses.php on line 167"

Metabolix [20.10.2013 13:16:03]

#

Laita WHERE vasta JOIN- ja ON-rivien jälkeen.

Siis luetko nyt yhtään noita virheilmoituksia? Tuossa sanotaan selvästi, että kyselyssä on INNER JOIN jotenkin väärin, ja etsimällä jonkin esimerkin saisit helposti selville, että JOIN tulee ennen WHEREä.

Antti Laaksonen [20.10.2013 13:25:29]

#

Metabolix kirjoitti:

Tuossa sanotaan selvästi, että kyselyssä on INNER JOIN jotenkin väärin,

Missä kohtaa niin sanotaan? Virheilmoitus kertoo vain, että virhe on ehkä jossain päin lähellä kyselyn loppuosaa.

Metabolix [20.10.2013 13:31:33]

#

Antti Laaksonen kirjoitti:

Metabolix kirjoitti:

Tuossa sanotaan selvästi, että kyselyssä on INNER JOIN jotenkin väärin,

Missä kohtaa niin sanotaan? Virheilmoitus kertoo vain, että virhe on ehkä jossain päin lähellä kyselyn loppuosaa.

MySQL:n virheilmoituksessa näkyy kysely alkaen kohdasta, jonka MySQL tunnistaa vääräksi. Tässä siis virheen täytyy olla joko kohdassa INNER JOIN tai juuri ennen sitä. Kyselyn koko loppuosa näytetään ilmoituksessa vain hämäyksen vuoksi tai sitä varten, että oikea kohta kyselystä löytyy helpommin: voihan olla, että kyselyssä on monta INNER JOIN -kohtaa, jolloin pelkkä INNER JOIN ei vielä kerro tarkasti, missä virhe on.

Tietoa oikeasta järjestyksestä löytyy ainakin hakusanoilla INNER JOIN WHERE, jotka ovat sikäli loogiset sanat, että Samin esimerkissä ovat jo kohdallaan kaikki osat paitsi WHERE ja uutena asiana (ja virheen aiheuttajana) on INNER JOIN.

merlin [20.10.2013 13:38:15]

#

Metabolix, luin ja googlailin juurikin tuota järjestystä - mutta valitettavasti en siihen vastausta heti löytänyt. Nyt toimii, suurkiitokset :)


Sivun alkuun

Vastaus

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

Tietoa sivustosta