Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: COUNT-funktio SQL-lauseessa

corto [04.05.2007 14:18:40]

#

Teen php:llä yksinkertaista foorumisovellusta ja yritän saada SQL-lauseessa määriteltyä count-funktion. Nykyinen toimiva lauseke on tässä:

SELECT DISTINCT Faiheet.*, Fkommentti.Fkommentti_teksti, Fkommentti.Fkommentti_aika, kayttajat.kayttaja
FROM ((Faiheet INNER JOIN Fkommentti ON Faiheet.Faiheet_id=Fkommentti.Fkommentti_id) INNER JOIN kayttajat ON kayttajat.kayttajaID=Fkommentti.kayttajaID)
ORDER BY Fkommentti_aika DESC

Tulostus on seuraava:
Faiheet_id Faiheet_nimi Fkommentti_teksti Fkommentti_aika kayttaja
----------------------------------------------------------------------------------------------
1 Testi1 testtest1 2007-04-29... user1
2 Testi2 testtest2 2007-04-28... user2

Tietokantarakenne on seuraava:

Faiheet
-------
Faiheet_id
Faiheet_nimi

Fkommentti
----------
Fkommentti_id
Fkommentti_teksti
Fkommentti_aika
Faiheet_id
kayttajaID

kayttajat
---------
kayttajaID
kayttaja
jne.

Tarkoitus olisi saada tuossa yllä olevassa lauseessa määriteltyä vielä lisäksi kuinka monta viestiä on kuhunkin aiheeseen tullut. Eli mihin väliin se "count"-pitäisi oikein laittaa, että tulostus olisi tällainen?

Faiheet_id Faiheet_nimi Fkommentti_teksti Fkommentti_aika kayttaja luku
-----------------------------------------------------------------------------------------------------
1 Testi1 testtest1 2007-04-29... user1 3
2 Testi2 testtest2 2007-04-28... user2 5

Antti Laaksonen [04.05.2007 23:52:06]

#

En ihan ymmärrä tuon kyselysi toimintaa, mutta ryhmittely (GROUP BY) voisi auttaa. Silloin tulostaulusta poimitaan kaikki annettujen kenttien eri yhdistelmät ja jokaisesta yhdistelmästä voidaan tutkia yhteisesti kaikkia rivejä, joilla kyseinen yhdistelmä esiintyy. Kuulostaa aika monimutkaiselta, mutta esimerkki selventää asiaa:

     viestiid       aiheid         aika
---------------------------------------
            1            1     2.5.2007
            2            1     2.5.2007
            3            2     2.5.2007
            4            1     3.5.2007
            5            2     4.5.2007
            6            3     4.5.2007

Nyt voidaan vaikka hakea näin:

SELECT aiheid, COUNT(viestiid) AS maara FROM Keskustelu GROUP BY aiheid

Ja tuloksena saadaan:

       aiheid        maara
--------------------------
            1            3
            2            2
            3            1

Eli näin voidaan selvittää, kuinka monta viestiä kuhunkin aiheeseen kuuluu. Ainoastaan GROUP BY -osassa esiintyviä kenttiä saa olla sellaisenaan SELECT-osassa. Muiden kenttien yhteydessä saa käyttää vain yhteenvetofunktioita (COUNT, SUM jne.), koska eri riveillä voi olla eri arvoja. Tätä tapaa voi käyttää myös silloin, kun rivit muodostetaan useammasta taulusta.

Käytännössä parempi ratkaisu voisi olla pitää kirjaa viestien määrästä aihekohtaisesti erillisessä kentässä, jotta sitä ei aina tarvitse laskea työläästi monesta taulusta. Tämä tosin sotii sitä periaatetta vastaan, että tietokannassa ei saisi olla samaa tietoa moneen kertaan, mutta tehokkuussyistä näin täytyy toisinaan menetellä.

corto [05.05.2007 13:02:19]

#

Ok, kiitos. Kokeilen kuitenkin ensin josko haluamani saa yhteen lauseeseen käyttämättä tuplatauluja.

Saan siis jokaisen aiheen viestimäärän seuraavalla lauseella:

SELECT count(Fkommentti.Faiheet_id) AS luku
FROM (Fkommentti LEFT JOIN Faiheet ON Faiheet.Faiheet_id=Fkommentti.Faiheet_id)
GROUP BY Faiheet.Faiheet_id

Eli tuloksena:

luku
----
   2
   2
   1

Pystyykö tuon yllä olevan liittämään mitenkään alkuperäiseen lauseeseen? Eli onko tämänkaltainen lausekehirviö mahdollinen?

SELECT (SELECT Faiheet.Faiheet_id, count(Fkommentti.Faiheet_id) AS luku
FROM (Fkommentti LEFT JOIN Faiheet ON Faiheet.Faiheet_id=Fkommentti.Faiheet_id)
GROUP BY Faiheet.Faiheet_id), Faiheet.Faiheet_nimi, Fkommentti.Fkommentti_teksti, Fkommentti.Fkommentti_aika, kayttajat.kayttaja
FROM ((Faiheet INNER JOIN Fkommentti ON Faiheet.Faiheet_id=Fkommentti.Fkommentti_id) INNER JOIN kayttajat ON
kayttajat.kayttajaID=Fkommentti.kayttajaID)

(nyt tuosta tulee "MySQL error 1241, Operand should contain 1 column(s)"...)

Hycke [07.05.2007 16:46:44]

#

Pitäisikö tuossa kyselyn joinissa olla

INNER JOIN Fkommentti ON Faiheet.Faiheet_id=Fkommentti.Faiheet_id

eikä

INNER JOIN Fkommentti ON aiheet.Faiheet_id=Fkommentti.Fkommentti_id

?

Viestien lukumäärän saat saat lisäämällä seuraavan kentän(toimii ainakin MS-SQL):

,(select sum(1) from fkommentti xx where xx.faiheet_id=faiheet.faiheet_id) as luku

Tai vaihtoehtoisesti

, luku = (select sum(1) from fkommentti xx where xx.faiheet_id=faiheet.faiheet_id)

corto [09.05.2007 16:01:12]

#

Ok, kiitokset!

Vastaus

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

Tietoa sivustosta