webForumDet fria alternativet

Statistik-hjälp

5 svar · 517 visningar · startad av Obbelix

ObbelixMedlem sedan okt. 2002257 inlägg
#1

Har en tabell som innhåller massa log-data grupperat per dag per "produkt". Nu skulle jag vilja ha ut summan på varje dag mellan två datum även om data saknas vissa dagar.
Om jag väljer 2007-01-03 till 2007-01-06 men det saknas data i tabellen på 2007-01-05 så kommer ju inte den dagen med i resultatet eftersom ingen logning gjordes den dagen på den produkten. Går det direkt i sql-frågan göra så att såna dagar blir med i resultatet men med värdet 0? Eller måste man göra det i programkoden?

Exempel på logdata:

product   view_count   bytes     d_mark
3         12           42563     2007-01-03
4         32           44323     2007-01-03
7         10           22564     2007-01-03
3         44           92563     2007-01-04
5         12           42561     2007-01-06
7         1            20        2007-01-06

Önskat resultat

d_mark        view_count   bytes
2007-01-03    54           109450
2007-01-04    44           92563
2007-01-05    0            0
2007-01-06    13           42581

Befintlig fråga

SELECT sd.d_mark, SUM(sd.view_count) AS view_count, SUM(sd.bytes) AS bytes
FROM stats_day sd
WHERE d_mark BETWEEN 2007-01-03 AND 2007-01-03
GROUP BY sd.d_mark
LarsGMedlem sedan dec. 200012 464 inlägg
#2

Du behöver en hjälptabell med maximalt lika många integervärden som antalet dagar i ditt tidsintervall.

SELECT sd.d_mark, 
  SUM(coalesce(sd.view_count,0)) AS view_count, 
  SUM(coalesce(sd.bytes,0)) AS bytes
  FROM integers left join stats_day sd
    on date '2007-01-02' + cast(integers.v as interval day) = sd.d_mark 
 WHERE integers.v between 1 and 4
 GROUP BY sd.d_mark

Det går att lägga den direkt i frågan,

SELECT sd.d_mark, 
  SUM(coalesce(sd.view_count,0)) AS view_count, 
  SUM(coalesce(sd.bytes,0)) AS bytes
  FROM ( values (1),(2),(3),(4)) as integers(v)
  left join stats_day sd
    on date '2007-01-02' + cast(integers.v as interval day) = sd.d_mark 
 WHERE integers.v between 1 and 4
 GROUP BY sd.d_mark

men en dylik tabell är ganska användbar.

ObbelixMedlem sedan okt. 2002257 inlägg
#3

Den klagar på raden med cast, men det kanske beror på att jag kör MySQL 5. Glömde skriva det i det första inlägget. Skäms på mig! :r

LarsGMedlem sedan dec. 200012 464 inlägg
#4

Du får ersätta det med dateadd.

ObbelixMedlem sedan okt. 2002257 inlägg
#5

Har försökt med följande fråga, men jag får samma resultat som innan. Har gjort en hjälptabell med en kolumn (i) som innehåller 31 rader, 1-31. Vad gör jag för fel?

 SELECT sd.d_mark,
 SUM(coalesce(sd.bytes,0)) AS bytes,
 SUM(coalesce(sd.view_count,0)) AS view_count
 FROM helper_table_integers hti LEFT JOIN stats_day sd
 ON date_add('2007-02-01',interval hti.i day) = sd.d_mark
 WHERE hti.i BETWEEN 1 AND 28
 GROUP BY sd.d_mark
ObbelixMedlem sedan okt. 2002257 inlägg
#6

Till slut så fick jag till det. Berodde dels på GROUP BY samt selecten på d_mark.

Fungerande fråga

SELECT date_add('2007-02-01',interval hti.i-1 day) AS d_mark,
  SUM(coalesce(sd.bytes,0)) AS bytes,
  SUM(coalesce(sd.view_count,0)) AS view_count
  FROM helper_table_integers hti LEFT JOIN stats_day sd
    ON date_add('2007-02-01',interval hti.i-1 day) = sd.d_mark
 WHERE hti.i BETWEEN 1 AND 28
 GROUP BY hti.i
130 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
127 ms — hämta tråd, inlägg och bilagor (db)