Pomoč SQL stavek
6 naročnikov
6 naročnikov
Zdravo!
Prosim za pomoč pri SQL stavku. Imam 3 tabele. Glavna tabela je tabela objave, kjer se shranjujejo objave uporabnikov. Druga in tretja sta tej tabeli podrejeni in se v prvo shranjujejo komentarji na te objave, v drugo pa ogledi teh objav. Moj namen je, da se mi v eni tabeli izpisuje po mesecih in letih sortirano število vseh objav nato pa še koliko unikatnih ljudi je komentiralo v tem mesecu in koliko unikatnih ljudi si je ogledalo objave v tem mesecu.
Takole imam sedaj, vendar mi prikazuje precej večje številke, kakor bi moralo biti.
SELECT
MONTH( FROM_UNIXTIME( statusi.datum ) ) AS mesec,
YEAR( FROM_UNIXTIME( statusi.datum ) ) AS year,
COUNT( statusi.id ) AS stevilo,
COUNT( distinct status_komentar.user_id) AS os_komentar,
COUNT( distinct status_ogled.user_id) AS os_ogled
FROM statusi
LEFT JOIN status_komentar ON statusi.id = status_komentar.status_id
LEFT JOIN status_ogled ON statusi.id = status_ogled.status_id
WHERE statusi.uporabnik_id = '1'
GROUP BY
MONTH( FROM_UNIXTIME( statusi.datum ) ) ,
YEAR( FROM_UNIXTIME( statusi.datum ) )
ORDER BY year DESC , mesec DESC
Torej problem je, da mi potem prikazuje večje številke v vseh poljih. Bi bil kdo toliko prijazen in mi pomagal?
Hvala!
11 odgovorov
Hitra rešitev bi bila s subqueriji:
SELECT
MONTH( FROMUNIXTIME( statusi.datum ) ) AS mesec,
YEAR( FROMUNIXTIME( statusi.datum ) ) AS year,
COUNT( statusi.id ) AS stevilo,
( SELECT distinct statuskomentar.userid FROM statuskomentar WHERE statusi.id = statuskomentar.statusid) AS oskomentar,
( SELECT distinct statusogled.userid FROM statusogled WHERE statusi.id = statusogled.statusid) AS osogled
FROM statusi
WHERE statusi.uporabnik_id = '1'
GROUP BY
MONTH( FROMUNIXTIME( statusi.datum ) ) ,
YEAR( FROMUNIXTIME( statusi.datum ) )
ORDER BY year DESC , mesec DESC
Preveri pa hitrost, ker znajo bit zelo počasni.
Torej imata dva uporabnika enak ID. Na tale SQL se ne spoznam, bolj mi je blizu ORACLE amapak tvojega problema se lotiš tako da najprej ugotoviš da koliko je dejansko stanje in potem delaš na enem primeru. Vrjetno maš preveč ohlapen pogoj. Probaj najprej samo dve tabeli povezat.
Okej sem ugotovil in popravil. Manjkalo je COUNT v subquery-ih. Vendar še vedno mi ne izpiše pravih števil. Če izvedem tale stavek:
SELECT COUNT( DISTINCT user_id )
FROM `status_komentar`
dobim recimo število 35, ko pa jih preštejem v prejšnji tabeli iz onega querija, jih imam pa 32. Tudi pri ogledih gre navskriž.
Pardon, pozabil modati cnt:
SELECT
MONTH( FROMUNIXTIME( statusi.datum ) ) AS mesec,
YEAR( FROMUNIXTIME( statusi.datum ) ) AS year,
COUNT( statusi.id ) AS stevilo,
( SELECT count(statuskomentar.userid) FROM statuskomentar WHERE statusi.id = statuskomentar.statusid GROUP BY statuskomentar.userid) AS oskomentar,
( SELECT count(statusogled.userid) FROM statusogled WHERE statusi.id = statusogled.statusid GROUP BY statusogled.userid) AS osogled
FROM statusi
WHERE statusi.uporabnik_id = '1'
GROUP BY
MONTH( FROMUNIXTIME( statusi.datum ) ) ,
YEAR( FROMUNIXTIME( statusi.datum ) )
ORDER BY year DESC , mesec DESC
Pa daj analiziraj vse tri subquerye in poglej kateri vrača več kot eno vrstico... A je tok težko to?
po mojih izkušnjah je včasih pri mysqlu bolje narediti več (enostavnih) queryev kot pa eno klobaso z miljon joini in subqueryi (indexom navkljub)
ob predpostavki, da gre za kombo php/mysql, bi jaz najprej nafilal array statusov (za key daš id), potem pa narediš še querya za komentarje in oglede in dofilaš omenjeni array (itak imaš vedno status_id)
Pa velikokrat se splača kakšne counte in podobne zadeve pohandlati že v logiki in izračune kar zapisati v tabelo. Sploh, ko je treba po tem nato še sortirati.