Olen tässä hetken pähkäillyt seuraavan ongelman kanssa:
Teen keskustelu forumia. Haluaisin, että kun tullaan keskustelualueelle niin tulostettaisiin kaikkien keskusteluiden ensimmäiset viestit eli aloitus viestit. Voisiko joku auttaa millaisella SQL käskyllä tämän saa toimimaan?
Ongelmanani on, että nyt tulostuvat kaikki viestit.
Olen yrittänyt seuravanlaisella SELECT komennolla:
SELECT id, otsikko, kirjoittaja, aika FROM keskustelu ORDER BY aika DESC
Pitäisikö tuossa olla jonkinlainen WHERE ehto?
Olen tätäkin kokeillut, mutta en ole onnistunut.
Teen keskustelu forumia. Haluaisin, että kun tullaan keskustelualueelle niin tulostettaisiin kaikkien keskusteluiden ensimmäiset viestit eli aloitus viestit. Voisiko joku auttaa millaisella SQL käskyllä tämän saa toimimaan?
Ongelmanani on, että nyt tulostuvat kaikki viestit.
Olen yrittänyt seuravanlaisella SELECT komennolla:
SELECT id, otsikko, kirjoittaja, aika FROM keskustelu ORDER BY aika DESC
Pitäisikö tuossa olla jonkinlainen WHERE ehto?
Olen tätäkin kokeillut, mutta en ole onnistunut.
Vastaukset 11
Vanhimmat
En kerro suoraa vastausta, mutta LIMIT x ratkasee pulmasi.
http://dev.mysql.com/doc/refman/5.0/en/select.html
Tyhmän aloittelijan onnea, ei toimi.
Kun laitan LIMIT 10 niin mukaan tulee myös vastaukset.
LIMIT isa tai jokin muu vastaava ei toimi???
mikä erottaa aloitus viestit muista viesteistä..
kai sinulla on joku kenttä mihin merkitset mikä on aloitusviesti ja mikä on vastaus vanhaan viestiin..
no kuitenkin ehdoksi vaan
where ehto = aloitusviesti
eli listaa ne kaikki mitkä ovat aloitusviestejä..
Kiitos kaikille avuista. Ongelma oli muussa, kuin SQL-lauseessa.
Nyt toimii.
SQL opas(http://dev.mysql.com/) antaa seuraavan määrittelyn select lauseelle:
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr, ...
[INTO OUTFILE 'file_name' export_options
| INTO DUMPFILE 'file_name']
[FROM table_references
[WHERE where_definition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_definition]
[ORDER BY {col_name | expr | position}
[ASC | DESC] , ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[FOR UPDATE | LOCK IN SHARE MODE]]
Limit ottaa parametrikseen ensimmäisen palautettavan rivin (ohjelmoija aloittaa laskemisen nollasta) ja palautettavien rivien määrän. Siis palauttaaksemme osumat kymmenen ja kahdenkymmenen välillä:
SELECT * FROM taulunnimi ORDER BY aika LIMIT 9,10;
Saako tuon LIMIT-lauseen toimimaan jotenkin niin, että tulostuisi viestipuu viestin alle tapaan josta voi seurata keskustelun kulkua kuten suomi24:llä?
Tällä hetkellä tulostuvat kaikki taulun keskustelut puumaisessa muodossa.
Saako LIMITin siis toimimaan jotenkin niin, että se katsoo viestin isan vai pitääkö käyttää WHEREä?
*Saako tuon LIMIT-lauseen toimimaan jotenkin niin, että tulostuisi viestipuu viestin alle tapaan josta voi seurata keskustelun kulkua kuten suomi24:llä?*
Ei, sulla on hieman sekasin ohjelmointi käsitteet viel. Tietokannasta haetaan SQL kielisellä kyselyllä haluttu tietojoukko, haluttuun muotoon se sitten tulostetaan esim PHP:llä
Tuo viestipuu systeemi on helppo toteuttaa, nyt kiire joten selostan sen huomenissa jos tarttet sitä.
*Saako LIMITin siis toimimaan jotenkin niin, että se katsoo viestin isan vai pitääkö käyttää WHEREä?*
LIMIT on yksinomaan rajoitus monta hakutulosta näytetään, optiona voi määritellä mistä eteenpäin näytetään. WHERE ehdoilla määrittelet mitä tuloksia haluat.
Ongelma ei ole vielä ratkennut.
Jos voit selvittää niin olen kiitollinen, koska ei oikein tahdo aueta.
Limit todella tekee sen minkä sanookin, eli rajoittaa. Lausehan määrittyi: [LIMIT {[offset,] row_count | row_count OFFSET offset}], eli lienee todellakin selvää, ettei lause veny toivomiisi mittasuhteisiin.
Tuntematta tietokantasi rakennetta varsinaiseen kysymykseesi on vaikea vastata.
Oletetaan että tietokantasi rakentuisi seuraavasti:
*viestitunnus (numero, ei automincrement)
kayttajatunnus (m-1 käyttäjiin)
otsikko
viesti
liittyy_viestiin (viittaa avaimeen)
Tosin sanoen tietokantasi voisi näyttää vaikka tältä (sinun kantasi on varmasti paremmin suunniteltu):
1 | kalle | hei | viesti 1 |
2 | mikko | sajdj | viesti 2 | 1
4 | marja | hupi | viesti 3 |
8 | mikko | Terve! | viesti 4 | 2
9 | mikko | jj | viesti 5 | 2
Esimerkki taulumme näyttäisi sivulle listattuna seuraavalta:
hei
|___sajdj
****|___Terve!
****|___jj
hupi
Nyt haluat palauttaa vain viestin 1 ja siihen liittyvät viestit. Huomaathan select -lauseen ongelman? Olet tottunut kirjoittmaan hakulauseeseen käsin mitä tietokannasta tulee palauttaa, mutta nyt sinulla ei ole moista tietoa. Tietokanta elää jatkuvasti.
Ongelman ratkaisuun tarvitset ohjelmalogiikkaa. Voit toteuttaa ratkaisun ohjelmakoodissa tai käyttää tietokannan omia "hienostuneempia" ominaisuuksia. MySQL tosin on perinteisesti ollut ominaisuuksiltaan rajoitettu tietokanta, mutta uudemmat versiot?
Huomioithan tehokkuusnäkökohdat.
Tuossahan tuo idea tuli, mutta tässä kuitenkin lupaamani esimerkki.
Huomioi sitten, että esimerkissä käytetty * joka ei hyvä, sekä functiokin tulostaa joka ei myöskään hyvä. Taulukko rakennetta sit kannattaa miettiä omiin tarpeisiisi sopivaksi, kuten viesteille ja käyttäjille ainaskin omat taulut.
Taulukko rakenne
id | ketju_id | vastattu_viestiin | otsikko | aika
id = juokseva numerointi
ketju_id = ketjun id numero (aloituksen id numero)
vastattu_viestiin = sen viestin id johon vastattu, aloitus viestille 0
// Functio lapsien tulostamiseen
function lapsia($x)
{
global $v_otsikkot, $v_id;
foreach ($v_otsikkot[$x] as $y => $otsikko)
{
echo "{$otsikko} | id = {$v_id[$x][$y]} ";
// Jos otsikon alle vastattu
if ($v_otsikkot[$v_id[$x][$y]])
{
echo '';
echo lapsia($v_id[$x][$y]);
echo '';
}
}
}
// Haetaan viestit
$sql = 'SELECT * FROM foorumi WHERE ketju_id = 2 ORDER BY vastattu_viestiin, aika';
$viestit = mysql_query($sql);
// Tallennetaan viestit muuttujiin
while ($data = mysql_fetch_assoc($viestit))
{
// Jos otsikon alle vastattu
if ($data['vastattu_viestiin'] != 0 and $data['vastattu_viestiin'] != $aloitus_id)
{
// Aloitus viestin id
$aloitus_id = !$aloitus_id ? $aloitus_id : $data['id'];
$v_otsikkot[$data['vastattu_viestiin']][] = $data['otsikko'];
$v_id[$data['vastattu_viestiin']][] = $data['id'];
}
// Ei vastattu
else
{
$id[$data['id']] = $data['id'];
$otsikot[$data['id']] = $data['otsikko'];
}
}
echo '';
foreach ($id as $x)
{
echo "{$otsikot[$x]} | id = {$id[$x][$y]} ";
// Jos otsikon alle vastattu
if ($v_otsikkot[$x])
{
echo '';
echo lapsia($x);
echo '';
}
}
echo '';
Tuosta sitten puuttuu tietokantaan yhdistämiset.
Ketju_id = määrittelee sen mikä ketju näytetään, tuo on helppo ottaa esim linkistä.
*MySQL tosin on perinteisesti ollut ominaisuuksiltaan rajoitettu tietokanta, mutta uudemmat versiot?*
Totta mutta riittävä peruskäyttöön, tosin uusin MySQL 5 sisältää paljon hyödyllisiä juttuja, joten uusin mysli on varteen otettava vaihtoehto. Harmi vaan, ettei tuota versiota vielä monessa paikkaa ole, monissa 4.0x jotka ei edes tue alikyselyäkään.