Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: [MySQL] Kaksi taulua, erinimiset sarakkeet

Sivun loppuun

Petja [20.03.2011 10:01:51]

#

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

esajeejee [20.03.2011 12:44:56]

#

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ä.

Petja [22.03.2011 16:52:32]

#

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).

Grez [22.03.2011 17:03:29]

#

Onko niissä kellonaikaa. Pelkän id:n perusteella on mahdotonta sanoa, kumpaan on lisätty viimeiseksi.

Petja [22.03.2011 17:08:41]

#

Grez kirjoitti:

Onko niissä kellonaikaa.

Nyt on myös timestamp-sarake.

Grez [22.03.2011 17:19:21]

#

No sittenhän se menee jokseenkin esajeejee:n esimerkin mukaan.

Petja [22.03.2011 17:25:12]

#

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?

AkeMake [22.03.2011 18:03:10]

#

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.

strtotime($forum_question['timestamp']) >= strtotime($forum_aswer['timestamp']) ? $uusin = $forum_question : $uusin = $forum_aswer;

Petja [22.03.2011 19:14:18]

#

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.

Metabolix [22.03.2011 19:22:30]

#

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.

esajeejee [22.03.2011 19:39:56]

#

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ä.

AkeMake [22.03.2011 19:43:53]

#

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.

Petja [22.03.2011 19:50:50]

#

AkeMake,
Skriptisi palauttaa Array. Mitä sillä on nyt tämän asian kanssa tekemistä? :O

Metabolix [22.03.2011 19:55:13]

#

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.

AkeMake [22.03.2011 19:55:26]

#

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

Petja [22.03.2011 20:00:38]

#

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?

esajeejee [22.03.2011 20:01:08]

#

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?

$query = "SELECT....";
$results = mysql_query( $query ) or die( mysql_error() ) // Pastee tämä errori tänne

print_r( mysql_fetch_assoc( $results ) );

Petja [22.03.2011 20:41:59]

#

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));

Macro [22.03.2011 22:03:41]

#

$results-muuttujan määrittelyrivin lopusta puuttuu puolipiste.

makumaku [22.03.2011 22:28:03]

#

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.

esajeejee [22.03.2011 23:04:50]

#

hupsistakeikkaavaan.. en kyllä jaksanu ihan editoriin asti tabata tuota varten mutta tässä puolipisteen kanssa

$query =	"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";
$results = mysql_query( $query ) or die( mysql_error() );
print_r( mysql_fetch_assoc( $results ) );

Petja [23.03.2011 06:47:51]

#

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.

esajeejee [23.03.2011 08:08:01]

#

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.

Petja [23.03.2011 16:02:28]

#

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.

esajeejee [23.03.2011 16:47:47]

#

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

Petja [23.03.2011 17:02:24]

#

On timestamp-tyyppiä.
Lisäsin taas uuden rivin vastaukset-osioon, mutta edelleenkin palauttaa typeksi question.

esajeejee [23.03.2011 17:21:00]

#

Tarkista tolla max queryllä että sen timestamp on varmasti suurempi tai uudempi

Petja [23.03.2011 17:30:10]

#

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ä.

esajeejee [23.03.2011 17:40:36]

#

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' )" );

Chiman [23.03.2011 17:41:27]

#

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.

Petja [23.03.2011 17:48:10]

#

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!

esajeejee [23.03.2011 18:02:55]

#

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'" );

Petja [23.03.2011 18:15:58]

#

On nyt manuaalinen. Ei edelleenkään korjaa! ????

esajeejee [23.03.2011 18:22:23]

#

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

Petja [23.03.2011 18:25:39]

#

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.

esajeejee [23.03.2011 18:32:10]

#

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

Petja [23.03.2011 18:34:39]

#

Problem! Vaikka ties kuinka monta riviä olen lisännyt vastauksiin pysyy edelleen skriptin tulostus question.

Petja [23.03.2011 20:25:39]

#

Niin, eli...?
Tämä tulostaa EDELLEENKIN question, vaikka olen lisännyt KUMPAANKIN TAULUUN uusia rivejä.

Grez [23.03.2011 20:30:58]

#

No mitä sulla on siellä answer taulussa? Onko ne lisätyt rivit saaneet isompia timestampeja.

Metabolix [23.03.2011 20:51:34]

#

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?

Petja [23.03.2011 21:00:56]

#

Sainkin toimimaan pienien koodiviritelmien jälkeen. Mutta sitten taas uusi juttu...

Tieto ei muutu siis toista aihetta lisättäessä.

esajeejee [24.03.2011 16:34:57]

#

Ohjelmointiputka-inside-meemiehdotus:

Kaksi taulua, yksi rivi

Petja [27.03.2011 08:50:54]

#

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.

Olli [27.03.2011 09:32:21]

#

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?

makumaku [27.03.2011 13:50:43]

#

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ä.

Petja [27.03.2011 13:52:27]

#

Selvä, pitääpi katsoa nuo.
Mutta tässä minun tapauksessani ei ole kyse virheestä (olettaakseni?). Miten hoidan asian?


Sivun alkuun

Vastaus

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

Tietoa sivustosta