07. april 2009 - 08:54Der er
10 kommentarer og 1 løsning
Meget indviklet query
Hej eksperter,
Jeg har nu siddet flere timer og kæmpet med en query, som jeg nu har givet lidt op over for.
Jeg vil nu prøve at forklare problemet. Jeg sender nyhedsbreve ud til mine brugere, men jeg er kun interesseret i at sende til dem, som gider læse mine breve. Derfor vil jeg gerne fjerne inaktive brugere fra maillisten. Mit kriterie for at fjerne dem er, hvis de ikke har læst ét af det seneste fem breve jeg har sendt dem.
Strukturen i "send_log" er: id | time | time_open | bruger_id | brev_id | read
Hvor read=1 hvis de har læst brevet. "time" er de tidspunkt jeg har sendt brevet, "time_open" er tidspunktet de har åbnet det, resten giver nok sig selv :)
Er det nogen der kan gennemskue en løsning på dette? Jeg vil kort sagt gerne have et udtræk med alle de bruger_id'er som ikke har læst ét af de fem seneste breve de har fået sendt.
splazz >> Det vil kræve at jeg løber hele listen igennem en while-løkke, hvilket jeg helst vil undgå - men det er klart et alternativ! Jeg gemmer time som datetime ja.
Sebastian >> Ja, det kan jeg se. Men jeg vil gerne fjerne brugere, der er faldet fra senere hen ligeledes. Derfor skal det være i betragtning af de seneste 5 breve. Som du forslår at fjerne dem der aldrig har læst nogen breve, er ikke en god ide. Da vil alle nye brugere blive fjernet og evt. gamle brugere der endnu ikke har fået sendt et brev.
Jeg vil allerhelst have en løsning med 5 breve - da jeg sender breve ud med forskelligt tidsmellemrum og til forskellige segmenter og derfor vil denne løsning ikke kunne laves særlig dynamisk.
Vælg alle brugere som IKKE er iblandt de brugere, som har læst et af de seneste 5 breve. Den forudsætter af dine primære nøgler er fortløbende ints. Jeg tager forbehold for fejl, skriver den i hånden... men den skulle være der nu.
SELECT * FROM bruger WHERE bruger.id NOT IN ( SELECT send_log.bruger_id FROM sendlog WHERE send_log.read = 1 AND send_log.brev_id IN ( SELECT brev.id FROM brev ORDER BY brev.id DESC LIMIT 5 ) )
Dette vil dog heller ikke virke optimalt, da alle brugere ikke modtagere alle breve. Derfor vil nogen blive mærket inaktive trods de måske kun har modtaget ét brev (grundet segmentering).
Din løsning vil også udvælge brugere der har modtaget under fem breve, hvilket gør at de endnu ikke har fået chancen for at læse det 5. brev.
Brugere som har fået tilsendt mindst 5 ulæste breve... men den tager ikke højde for, at det skal være de seneste 5 som er ulæste. Om ikke andet, så kan den måske være inspiration.
SELECT bruger.id FROM bruger INNER JOIN send_log ON bruger.id = send_log.bruger_id WHERE send_log.read = 0 GROUP BY bruger.id HAVING COUNT(send_log.brevid) >= 5
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.