Olen yritellyt etsiä Googlesta ohjeita tähän, mutta toistaiseksi en ole törmännyt vielä. Tarkoitus olisi saada noudettua kahden taulun tiedot, joissa erinimiset sarakkeet.
Noudetaan tietokannasta taulut forum_answer
ja forum_question
, sarakkeet detail
(taulu: forum_question
) ja a_answer
(taulu: forum_answer
) joista uusimmat (viimeksi päivitetyt/lisätyt) rivit ja rajataan LIMIT 2
. Kuinka toteutetaan?
Selkeämmin:
Kun lisään uuden rivin tauluun forum_answer
tai tauluun forum_question
näkyy se skriptin tulostuksessa, aina se ensimmäisenä mitä on viimeksi muokattu.
Jotain:
SELECT * FROM forum_answer, forum_question LIMIT 2
Haluatko siis yhden uusimman molemmmista? Vai 2 uusinta molemmista? vai 2 uusinta siitä huolimatta oliko ne kysymyksiä vai vastauksia? Tää toteuttaa jälkimmäisen
SELECT detail, timestamp, 'question' AS type FROM forum_question UNION ALL SELECT a_answer, timestamp, 'answer' AS type FROM forum_answer ORDER BY timestamp DESC LIMIT 2
Örr olettaen siis että sulla on timestamp kolumni. Jos sulla on auto_increment id kolumni niin korvaa timestamp sillä.
esajeejee kirjoitti:
Haluatko siis yhden uusimman molemmmista? Vai 2 uusinta molemmista? vai 2 uusinta siitä huolimatta oliko ne kysymyksiä vai vastauksia?
Olen muokannut tätä ideaa (kahden rivin sijasta, haluan yhden). En halua noutaa ensimmäistä riviä molemmista, vaan haluan vain ensimmäisen rivin (se mikä on viimeksi lisätty) riippumatta siitä kummassa taulussa se on.
Kummassakin taulussa on kolumnit id
(auto_increment).
Onko niissä kellonaikaa. Pelkän id:n perusteella on mahdotonta sanoa, kumpaan on lisätty viimeiseksi.
Grez kirjoitti:
Onko niissä kellonaikaa.
Nyt on myös timestamp
-sarake.
No sittenhän se menee jokseenkin esajeejee:n esimerkin mukaan.
No eipä vaan näytä menevän. :(
Grez kirjoitti:
jokseenkin
Eli siis...? Jos tuo koodi ei ole täydellinen, niin miten siitä sellaisen sitten saa?
Ei varmastikaan paras ratkaisu, mutta pitäisihän sen toimia niinkin, että hakee vain molemmista tauluista erikseen yhden uusimman ja vertaa PHP:llä, kumpi on uudempi.
SELECT * FROM forum_question ORDER BY timestamp DESC LIMIT 1 SELECT * FROM forum_answer ORDER BY timestamp DESC LIMIT 1
Seuraavassa siis se uusin rivi löytyy samannisestä taulukosta, kuin taulu, josta rivi on haettu.
Hmm...?
mysql_connect("$host", "$username", "$password")or die("cannot connect"); mysql_select_db("$db_name")or die("cannot select DB"); $sql="SELECT * FROM forum_question ORDER BY timestamp DESC LIMIT 1"; $sql2="SELECT * FROM forum_answer ORDER BY timestamp DESC LIMIT 1"; strtotime($sql['timestamp']) >= strtotime($sql2['timestamp']) ? $uusin = $sql : $uusin = $sql2; $result=mysql_query($uusin) or die(mysql_error()); if($result['detail']=="") { $uusin=$result['a_answer']; }else{ $uusin=$result['detail']; } print $uusin; mysql_close();
Huomaan itsekin, että tässä koodissa on jokin puute, mutta en tajua missä se oikein on.
Voi äly hoi nyt. Oletko yhtään ajatellut, mitä koodisi tekee? Seuraava koodi on aivan yhtä järkevä:
$antti = "Antti"; $matti = "Matti"; if ($antti["ikä"] > $matti["ikä"]) { echo "Antti on vanhempi kuin Matti!\n"; }
Lainaan AkeMakea valikoivasti: "Seuraavassa siis se uusin rivi ... on haettu." Sinun koodissasi tämä ehto ei nyt täyty. Ei se teksti itsestään tietokannan dataksi muutu.
Jos haluat vain yhden uusimman riippumatta
SELECT detail, timestamp, 'question' AS type FROM forum_question UNION ALL SELECT a_answer, timestamp, 'answer' AS type FROM forum_answer ORDER BY timestamp DESC LIMIT 1
Jossei toimi niin pastee mysql error
Jos taulu on iso ( vaikka tuskin se on ? ) niin suosittelen jonkinnäköstä where timestamp ehtoa jolloin query käyttää indeksejä.
Tässä pitäisi olla toimivampi koodi. En tosin ole testannut, mutta ellei huolimattomuusvirheitä tullut, niin pitäisi toimia.
$yhteys=mysql_connect($host, $username, $password) or die("cannot connect"); mysql_select_db($db_name, $yhteys) or die("cannot select DB"); $sql="SELECT * FROM forum_question ORDER BY timestamp DESC LIMIT 1"; $sql2="SELECT * FROM forum_answer ORDER BY timestamp DESC LIMIT 1"; $forum_question=mysql_query($sql, $yhteys) or die(mysql_error()); $forum_question=mysql_fetch_array($forum_question, MYSQL_ASSOC); $forum_answer=mysql_query($sql2, $yhteys) or die(mysql_error()); $forum_answer=mysql_fetch_array($forum_answer, MYSQL_ASSOC); strtotime($forum_question['timestamp']) >= strtotime($forum_answer['timestamp']) ? $uusin = $forum_question : $uusin = $forum_answer; mysql_close();
Nyt sinulla on taulukossa $uusin kaikki uusimman rivin tiedot, jotka saat ulos normaalisti $uusin['a_answer'], $uusin['detail'] ja sitä rataa..
// esajeejee nakkasikin sitten sen haun, jolla saa uusimman rivin yhdellä tietokantahaulla ilman mitään ylimääräisiä kikkailuja. Jos se vain toimii, niin tietenkin se on helpompi tapa hakea uusin rivi.
AkeMake,
Skriptisi palauttaa Array. Mitä sillä on nyt tämän asian kanssa tekemistä? :O
Opetelkaa nyt ihmiset oikeasti koodaamaan ja debuggaamaan. Jos mysql_query palauttaisi taulukon (jota siis vertailussa tarvitaan), mitä varten mysql_fetch_array vielä myöhemmin olisi? Tai kääntäen: jos kerran mysql_fetch_array palauttaa sen taulukon (jota siis vertailussa tarvitaan), miksi se on vasta lopussa eikä jo ennen vertailua?
Jos funktioiden toiminnot ja paluuarvot ovat jotenkin epäselvät, tulokset voi helposti tarkistaa lisäilemällä var_dump-rivejä joka väliin.
Löysin tuosta myöhemmän tarkistuksen yhteydessä muutakin pientä ja vähän suurempaakin virhettä. Nyt kuitenkin sain korjattua kaikki mitä siitä vain löysin. Suosittelisin kuitenkin ensin kokeilemaan, jos saisit tuon esajeejeen tietokantahaun toimimaan, koska se on kaikessa yksinkertaisuudessaan paljon parempi tapa kuin oma viritelmäni. Jos et sitä saa toimimaan, niin sitten voisi tehdä tällä minun tavallani.
// Metabolix varmaan tarkoitti, että minun viritelmäni on täysin päin honkia? No, kokeilin taas korjata sitä ja eiköhän tuon nyt jo pitäisi toimia. Melkoisesti tuosta löytyi huolimattomuusvirheitä, kun muka nopeasti yritin sen ensimmäisellä kerralla saada kokoon. Kiitos vain metabolix rohkaisevista sanoista. Ai, että kohottaa itsetuntoa. :P
Metabolix kirjoitti:
Opetelkaa nyt ihmiset oikeasti koodaamaan ja debuggaamaan.
Sitähän tässä juuri ollaan tekemässä.
Mutta tuosta esajeejeen koodista:
Eli ensiksi suoritan tuon kyselynä? Ja sitten?
En tosiaankaan ole mikään huippukoodari, kuten monet teistä varmasti on?
Ensimmäisenä mitä tulis mielee miksei toi mun query toimis olis että kolumnit forum_question.detail ja forum_answer.a_answer käyttävät eri merkistökoodausta. Tai jotenkin muutenkin ovat tyypeiltään täysin erilaisia.
lainaus:
Eli ensiksi suoritan tuon kyselynä? Ja sitten?
esajeejee kirjoitti:
Ensimmäisenä mitä tulis mielee miksei toi mun query toimis olis että kolumnit forum_question.detail ja forum_answer.a_answer käyttävät eri merkistökoodausta. Tai jotenkin muutenkin ovat tyypeiltään täysin erilaisia.
Niinpä, niin... Tutkinpa asiaa.
Tuloksena, että forum_answer
käyttää utf8_general_ci
ja forum_question
käyttää latin1_swedish_ci
. Olen nyt muuttanut koodaukset samaksi.
Käytössä on nyt esajeejeen versio.
Tästä huolimatta virheilmoitus on:
Parse error: syntax error, unexpected T_STRING in XXXXX on line 305
Rivi 305:
print_r(mysql_fetch_assoc($results));
$results-muuttujan määrittelyrivin lopusta puuttuu puolipiste.
Jos oikeasti haluaa koodailla enemmän niin suosittelen jonkun kunnollisen editorin käyttöä. Esim tuollaisissa puolipisteen puuttumisissa kunnollinen editori huutaisi jo sen verran että varmasti käyttäjä huomaisi asian ennekuin ehtii edes ajaa koodia.
hupsistakeikkaavaan.. en kyllä jaksanu ihan editoriin asti tabata tuota varten mutta tässä puolipisteen kanssa
Hyvin sain toimimaan!
Itselleni tein seuraavanlaisen ratkaisun:
$lista=mysql_fetch_assoc($results);
Ja sitten vaan printtailen tyyliin $lista[" ... "]
.
Mutta kun lisään uuden rivin tauluun a_answer
näytetään tämän skriptin tulostuksessa vain kysymys, eikä sitä vastausta, eli siis $lista["type"]
palauttaa aina question
, vaikka lisäisinkin uuden rivin vastaukset-tauluun.
Kun lisäsit uuden rivin, lisäsitkö siihen myös korkeamman timestamp luvun, kuin mitä question taulussa korkein on? Mitä tämä tulostaa:
SELECT MAX( timestamp ), 'question' AS type FROM forum_question UNION ALL SELECT MAX( timestamp ), 'answer' AS type FROM forum_answer
Esim tulostus vois tyyliin olla
MAX( timestamp ) type 1300476742 question 1300627212 answer
Mistä näkee että vastaus on tulossa seuraavaks.
Suoritin phpMyAdminissa. Tulostuksena:
MAX( timestamp ) type 2011-03-23 06:42:12 question 2011-03-23 06:40:31 answer
Luulenpa, että tämä johtuu ajan formaatista. Ei näet ole UNIX-aikaleima.
Tuostaha näkyy että uusin kysymys on 2 minsaa uudempi kuin uusin vastaus joten kysymys kuuluukin tulla siitä querystä ?
Ja jos tyyppinä on timestamp niin niitä säilötään unix aikaleimoina ja muunnetaan vasta queryttäessä tuohon muotoon. Joten kun vertaat kahta mysql aikaleimaa toisiinsa niin vertailu tapahtuu niissä säilötyissä numeroissa eikä output stringeissä.
Jos tuo timestamp kolumni on taas tyyppiä datetime niin vaihda se ihmeessä timestamp tyypiksi koska se vie 2x vähemmän tilaa ja et tule tarvitsemaan datetimä tossa kolumnissa muutenkaa
On timestamp-tyyppiä.
Lisäsin taas uuden rivin vastaukset-osioon, mutta edelleenkin palauttaa typeksi question.
Tarkista tolla max queryllä että sen timestamp on varmasti suurempi tai uudempi
Tyhjensin kummatkin taulut. Sitten lisäsin uuden rivin kysymyksiin, sen jälkeen vastauksiin. Sitten katsoin tuolla max-queryllä, mutta edelleen question ensimmäisenä.
Edit: Lisäsin nyt vielä myöhemmin uuden rivin kysymyksiin.
Petja kirjoitti:
mutta edelleen question ensimmäisenä.
Eli katsoit max queryllä että questioniolla on suurempi timestamp? vaikka se on lisätty myöhemmin?
Tyhjennä taulu taas ja koita vaikka läpällä tämmöstä:
mysql_query( "INSERT INTO forum_answers ( timestamp, a_answer ) VALUES( FROM_UNIXTIME( 10 ), 'vastaus' )" ); mysql_query( "INSERT INTO forum_questions ( timestamp, detail ) VALUES( FROM_UNIXTIME( 1 ), 'kysymys' )" );
Ei ole olennaista kumpi on ensimmäisenä, koska max-kyselyssä ei ole järjestämistä (order by), vaan kummassa on tuoreempi aikaleima. Katso sitten mitä se varsinainen oikea kysely palauttaa ja vertaa aikaleimoihin.
Ei, kyllä tuo aikaleima on tuossa kysymyksessä uudempi kuin vastauksessa, vaikka vastaus on todellisuudessa uudempi.
Edit: Koitin nyt myös tuota esajeejeen antamaa lisäysjuttua. Ensinäkin taulujen nimet eivät ole monikossa, eli forum_questions
on forum_question
. Mutta asiaan... Tuo toimi ihan moitteettomasti siten, että vastaus oli uudempi. Tämähän ei kuitenkaan asiaa vielä ratkaise!
Suosittelen semmosta purkkaviritystä, että lisäät timestampin aina manuaalisesti phplla:
Eli ainakun lisäät rivin niin
$timestamp = time(); mysql_query( "INSERT INTO forum_answer ( timestamp, a_answer ) VALUES ( FROM_UNIXTIME( $timestamp ), 'kysymys'" );
On nyt manuaalinen. Ei edelleenkään korjaa! ????
Copypastee nämä suoraan phpmyadminiin:
SELECT MAX( timestamp ), 'question' AS type FROM forum_question UNION ALL SELECT MAX( timestamp ), 'answer' AS type FROM forum_answer
Copypastee tulos tänne
SELECT detail, timestamp, 'question' AS type FROM forum_question UNION ALL SELECT a_answer, timestamp, 'answer' AS type FROM forum_answer ORDER BY timestamp DESC LIMIT 1
Copypastee myös tulos tänne
MAX( timestamp ) type 2011-03-23 18:21:26 question 1970-01-01 02:00:10 answer
detail timestamp type juopporalli! 2011-03-23 18:21:26 question
Otin noissa testeissäni vähän omituisia nimiä aiheille. Ettette ihmettele juopporalli.
2011 on tuoreempi kuin 1970... problem?
detail timestamp type asasdas 2011-03-23 18:27:56 answer
MAX( timestamp ) type 2011-03-23 18:27:31 question 2011-03-23 18:27:56 answer
Tein varmuuden vuoks vielä täysin identtiset taulut (tosin käytän suoraa phpmyadmin joten timestamp tulee mysql:ltä.
Lisäsin vastauksen 30 sekuntia myöhemmin ja sen aikaleima on uudempi joten se on tuloste tuossa alkuperäisessa queryssä kuten ylhäällä näkyy
Problem! Vaikka ties kuinka monta riviä olen lisännyt vastauksiin pysyy edelleen skriptin tulostus question
.
Niin, eli...?
Tämä tulostaa EDELLEENKIN question
, vaikka olen lisännyt KUMPAANKIN TAULUUN uusia rivejä.
No mitä sulla on siellä answer taulussa? Onko ne lisätyt rivit saaneet isompia timestampeja.
Enemmänkin kysyisin, mitä siinä skriptissä nyt on. Onko siinä tuo jälkimmäinen UNION-kysely, niin kuin pitää, vai ehkä nuo MAX(timestamp)-kyselyt, joilla oli tarkoitus vain katsoa tauluja erikseen?
Sainkin toimimaan pienien koodiviritelmien jälkeen. Mutta sitten taas uusi juttu...
Tieto ei muutu siis toista aihetta lisättäessä.
Ohjelmointiputka-inside-meemiehdotus:
Kaksi taulua, yksi rivi
Laitan tähän aiheeseen vielä jatkoa, ennen kuin tippuu uudet keskustelut -sivulta.
Tämä ei siis edelleenkään huomioi aiheita, vaan tulostaa AINA kommentin. Ensimmäistä aihetta lisättessä tämä kylläkin tulostaa aiheen, mutta heti vaihtaa toimintaansa, kun lisätään kommentti. Tämän jälkeen uusien aiheidenkaan lisääminen ei vaikuta asiaan.
makumaku kirjoitti:
Jos oikeasti haluaa koodailla enemmän niin suosittelen jonkun kunnollisen editorin käyttöä. Esim tuollaisissa puolipisteen puuttumisissa kunnollinen editori huutaisi jo sen verran että varmasti käyttäjä huomaisi asian ennekuin ehtii edes ajaa koodia.
Notepad++ ei tee tätä. Mistähän ko. ominaisuuden saa käyttöön?
Itsellä on yleensä käytössä joko phpDesigner 7 tai NetBeans PHP IDE.
Nämä kumpikin osaa näyttää jos puolipisteitä puuttuu, ja tietenkin myös näyttävät monia muitakin virheitä.
Selvä, pitääpi katsoa nuo.
Mutta tässä minun tapauksessani ei ole kyse virheestä (olettaakseni?). Miten hoidan asian?
Aihe on jo aika vanha, joten et voi enää vastata siihen.