30. januar 2010 - 13:56Der er
13 kommentarer og 1 løsning
Problem med at tælle antal nye poster
Hej eksperter. Jeg har prøvet på alle tænkeligt måder, at få udregnet hvor mange ulæste poster der er, men det vil bare ikke lykkes for mig.
Systemet foregår sådan at man har muligheden for at skrive breve til andre hvori andre kan skrive i. f.eks. ligesom facebook.
Her er mine tabeller ser således ud [code]CREATE TABLE IF NOT EXISTS `post` ( `ID` int(11) NOT NULL auto_increment, `fra` int(11) NOT NULL, `til` int(11) NOT NULL, `title` varchar(255) NOT NULL, `text` text NOT NULL, `created` timestamp NOT NULL default NULL, `last_post_date` timestamp NOT NULL default NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `post_beskeder` ( `ID` int(11) NOT NULL auto_increment, `postID` int(9) NOT NULL, `text` text NOT NULL, `author` int(9) NOT NULL, `created` timestamp NULL default NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `post_views` ( `postID` int(11) NOT NULL, `userID` int(11) NOT NULL, `last_view` timestamp NULL default NULL, PRIMARY KEY (`postID`,`userID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;[/code]
Det resultat jeg har brug for er, at tælle alle de poster hvor `post_views`.`last_view` er større end `post`.`last_post_date` OG hvor `post_views`.`user` = '84' og `post`.`til` eller `post`.`fra` = '84'.
Jamen jeg vil godt give et bud hvis jeg kan vaere sikker paa at jeg forstaar sammenhaengen.
Jeg gaar ud fra at du et eller andet sted har en tabel User med ID og navn og at de tal der staar i post.fra, post.til, post_beskedder.author, og post_views.userID refererer til id i User.
Saa gaar jeg ud fra at naar user 1 sender et nyt brev til user 2 saa oprettes der en ny linie i tabel post og post.created og post.lastpost timestamp fyldes ud med afsendelsestidspunktet.
Naar saa user 2 svarer paa brevet eller user 3 skriver i brevet saa oprettes der en ny linie i tabel post_beskeder. post_beskedder.postID = post.ID for det brev der svares paa. Baade post_beskedder.created og post.last_post_date fyldes ud med timestampet for afsendelsestidspunktet for beskedden.
Det forventes saa at userne vil holde oeje med beskedder paa de breve de har sendt eller modtaget. Naar en bruger laeser beskedderne for et brev saa laves der en ny linie i tabellen post_views hvor post_views.postID = post.ID for det brev hvorfra beskedder laeses, post_views.userID = user.ID for den user der laeser, og post_views.last_view faar timestampte for det tidspunkt der laeses paa.
Er det alt sammen korrekt? Hvis noget ikke er korrekt saa ret mig. Det er vigtigt.
Saa vil du for en bestemt user taelle hvor mange beskedder der er sendt til de breve useren har sendt eller modtaget. Du synes at definere en ulaest besked ved at post_views.last_view er stoerre end post.last_post_date. Det virker overraskende, jeg ville have troet at det var omvendt, at hvis et brev havde beskedder med et STOERRE timestamt, altsaa senere, end timestampet for hvornaar useren har laset sidst saa har det brev ulaeste beskedder. Venligst bekraeft at det er saadan.
Saa er der endnu et spoergsmaal. Det sidste felt i post har typen timestamp men navnet last_post_date. Det er da vel datoen og tiden for den sidste post der vises, ikke bare datoen. Korrekt?
Og saa en kommentar: Ved at taelle i hvor mange tilfaelde post.last_post_view er stoerre end post_view.last_view saa faar du ikke noedvendigvis antallet af ulaeste beskedder men antallet af breve der indeholder ulaeste beskedder. Et brev kan velsagtens have modtaget mere end en besked siden useren laeste dem sidst. Er det i orden bare at taelle hvormange breve har ulaeste beskedder? Hvis du vil have antallet af ulaeste beskedder skal vi ogsaa ind og sammenligne med post_beskedder.created.
Det var mange ting - som du vel egenlig skulle have forklaret i dit spoergsmaal. Jeg afventer dit svar, og hvis det er fyldestgoerende gaar jeg i gang med at udarbejde en loesning.
Okay prøver lidt mere detaljeret. Forresten en fejl at der er en `text` col i `post` tabellen. Det bliver selfølgelig hentet fra `post_beskeder`.
Hvis vi har brugerene [code]--- `users` --- userID | username 1 | Gunnar 2 | Peter[/code]
Gunner skriver et brev til Peter, og det bliver indsat i tabellerne `post` og `post_beskeder`med værdierne: [code]--- `post` --- ID | fra | til | title | created | last_post_date 1 | 1 | 2 | Test | 2010-02-30 22:30:00 | 2010-02-30 22:30:00[/code] [code]--- `post_beskeder` --- ID | postID | text | author | created 1 | 1 | Tester | 1 | 2010-02-30 22:30:00[/code]
Sammentidigt bliver Gunnar sat ind i `post_views`, da han ved hvad der er i tråden allerede. [code]--- `post_views` --- postID | userID | last_view 1 | 1 | 2010-02-30 22:30:00[/code]
5 minutter efter ser Peter så, at der er kommet en post fra Gunnar i hans indbakke, og han klikker ind på det. Når han så er inde på denne post, bliver der sat ind i `post_views: [code]--- `post_views` --- postID | userID | last_view 2 | 2 | 2010-02-30 22:35:00[/code]
Og når så Peter svarer så på Gunnars post, bliver `last_post_date` opdateret i `post` og der bliver indsat en ny række i `post_beskeder`. Herefter bliver `post_views` opdateret så vi ved, at Peter han har læst denne post. [code]--- `post` --- UPDATE ID | fra | til | title | created | last_post_date 1 | 1 | 2 | Test | 2010-02-30 22:30:00 | 2010-02-30 22:37:00[/code] [code]--- `post_beskeder` --- ID | postID | text | author | created 2 | 1 | OK | 2 | 2010-02-30 22:37:00[/code] [code]--- `post_views` --- UPDATE postID | userID | last_view 2 | 2 | 2010-02-30 22:37:00[/code]
Nu er Gunnars last_views altså ældre end `last_post_date` og derfor har han 1 ulæst post.
Håber det klarede det hele lidt mere op.
Og forresten
timestamp NOT NULL default NULL > Dette NULL betyder bare '0000-00-00 00:00:00'.
Men er der ikke et par trykfejl i din historie over Gunnar og Peter? Der forekommer i fortaellingen kun et brev, det der er indfoert i post med ID = 1. Skulle postID saa ikke have vaeret 1 i post_views klokken 22:35 og 22:37? Hvis virkelig det at Peter klikker paa Gunnars brev skaber et nyt postID som ikke svarer til nogen ID i post saa haenger tabellerne ikke sammen og jeg vil ikke kunne lave SQL queries paa dem.
Saa er det vel saadan at efter at Peter klokken 22:37 har svaret paa Gunnars brev saa kan han klokken 22:38 sende endnu et svar: "Forresten jeg glemte at sige...". Saa vil Gunnar have to ulaeste beskedder til sit brev. Hvis vi sammenligner Gunnar's last_views med last_post_date saa faar vi tallet 1, at der er et brev med ulaeste beskedder. Er resultatet 1 hvad du er ude efter, antallet af breve med ulaeste beskedder, eller er du noedt til at have resultatet 2, antallet af ulaeste beskedder? Jeg spurgte om det samme i #2. Jeg fik ikke svar, men det er helt essentielt at vaere klar paa dette punkt.
Saa lad mig faa dit svar paa disse to punkter saa jeg kan komme i gang.
I saafald skulle denne query virke, d.v.s. hvis det er bruger 1's ulaeste breve du vil have. Hvis du kalder queryen for eksempel fra en php site vil du nok bruge en variabel for bruger og saa sige: "...AND v.userID = $user.."
SELECT count(*) FROM post p JOIN post_views v ON p.ID=v.postID AND p.fra = v.userID OR p.til = v.userID AND v.userID = 1 WHERE p.last_post > v.last_view GROUP BY p.ID
To kommentarer: (1) Dit spoergsmaal var ikke vanskeligt da foerst vi havde overkommet vanskelighederne ved at kommunikere precist hvad spoergsmaalet var.
(2) Din tabelstruktur er meget for indviklet og med redundant data saasom tidspunktet for en begivenhed der bliver bevaret i tre forskellige tabeller. Hvis det er noget du skal bruge serioest vil jeg anbefale at du opretter et nyt spoergsmaal saasom: "Jeg har disse tabeller...." og genfortaelle Gunner og Peter historien (men med korrekte data) "...hvordan kan det forenkles?"
For test havde jeg lavet mine egne tabeller hvor querien virkede. Saa omsatte jeg tabel- og kolonnenavnene til kdjweb's navne. For nu at teste testen har jeg oprettet nye tabeller med identiske navne og med identiske data som i #3. Men foer jeg kunne afproeve querien paany doede phpMyAdmin for mig (paa one.com). Jeg har nu ventet en time for at se om den kom igen, men stadig ingen forbindelse. Jeg vil nu kontakte one.com for at hoere hvad der er galt og saa vende tilbage naar der er liv.
Jeg giver scriptet paa de tabeller jeg oprettede og de data jeg puttede i dem. Med de tabeller og data giver det foelgende query resultatet 1 hvilket det skulle:
SELECT count(*) FROM post p JOIN post_views v ON p.ID=v.postID AND p.fra = v.userID OR p.til = v.userID AND v.userID = 1 WHERE p.last_post_date > v.last_view GROUP BY p.ID
Tabeller og data:
CREATE TABLE post(ID INT, fra INT, til INT, titel VARCHAR(10), created DATETIME, last_post_date DATETIME);
CREATE TABLE post_beskeder(ID INT, postID INT, tekst VARCHAR(10), author INT, created DATETIME);
DROP TABLE IF EXISTS post; CREATE TABLE post(ID INT, fra INT, til INT, titel VARCHAR(10), created DATETIME, last_post_date DATETIME);
DROP TABLE IF EXISTS post_beskeder; CREATE TABLE post_beskedder(ID INT, postID INT, tekst VARCHAR(10), author INT, created DATETIME NOT NULL , viewed DATETIME NULL);
INSERT INTO post VALUES(1,1,2,'Test', '2010-01-30 22:30:00', '2010-01-30 22:37:00'); INSERT INTO post_beskeder (ID, postID, tekst, author, created) VALUES (1,1,'Tester', 1, NOW()); INSERT INTO post_beskeder (ID, postID, tekst, author, created) VALUES (2,1,'Ok', 2, NOW()); INSERT INTO post_beskeder (ID, postID, tekst, author, created) VALUES (3,1,'Tester', 1, NOW()); INSERT INTO post_beskeder (ID, postID, tekst, author, created) VALUES (4,1,'Tester', 2, NOW()); INSERT INTO post_beskeder (ID, postID, tekst, author, created) VALUES (5,1,'Tester', 1, NOW());
SELECT count(*) FROM post_beskeder WHERE PostId in ( SELECT id FROM post WHERE '1' in (fra, til) ) AND viewed is NULL AND author != '1'
/* Når der er en som læser en post_besked så skal viewed blot sættes til NOW() */
Hvis du vil have de post som har ikke sete beskedder samt hvormange kan du bruge denne DROP TABLE IF EXISTS post; CREATE TABLE post(ID INT, fra INT, til INT, titel VARCHAR(10), created DATETIME, last_post_date DATETIME);
DROP TABLE IF EXISTS post_beskedder; CREATE TABLE post_beskedder(ID INT, postID INT, tekst VARCHAR(10), author INT, created DATETIME NOT NULL , viewed DATETIME NULL);
INSERT INTO post VALUES(1,1,2,'Test', '2010-01-30 22:30:00', '2010-01-30 22:37:00'); INSERT INTO post VALUES(2,1,2,'Test', '2010-01-30 22:30:00', '2010-01-30 22:37:00'); INSERT INTO post_beskedder (ID, postID, tekst, author, created) VALUES (1,1,'Tester', 1, NOW()); INSERT INTO post_beskedder (ID, postID, tekst, author, created) VALUES (2,1,'Ok', 2, NOW()); INSERT INTO post_beskedder (ID, postID, tekst, author, created) VALUES (3,1,'Tester', 1, NOW()); INSERT INTO post_beskedder (ID, postID, tekst, author, created) VALUES (4,1,'Tester', 2, NOW()); INSERT INTO post_beskedder (ID, postID, tekst, author, created) VALUES (5,1,'Tester', 1, NOW()); INSERT INTO post_beskedder (ID, postID, tekst, author, created) VALUES (1,2,'Tester', 1, NOW()); INSERT INTO post_beskedder (ID, postID, tekst, author, created) VALUES (2,2,'Ok', 2, NOW());
SELECT PostId, count(*) FROM post_beskedder WHERE PostId in ( SELECT id FROM post WHERE '1' in (fra, til) ) AND viewed is NULL AND author != '1' GROUP BY PostId HAVING count(*) > 0
/* Når der er en som læser en post_besked så skal viewed blot sættes til NOW() */
kdjweb, bare lige den kommentar at det skuffer mig lidt. Jeg mener at have gjort en indsats. Maaske synes du ikke at det var noget.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.