webForumDet fria alternativet

Summera besökare mellan två veckor

Databaser & SQL

5 svar · 446 visningar · startad av doggelito

Medlem sedan juni 20003 076 inlägg
Frågan#1

Jag försöker summera antal besökare en site har haft veckovis men har kört fast.

ALTER PROCEDURE [dbo].[Stat_GetWeekUniqueVisitors]
	@StartDate datetime = NULL,
	@EndDate datetime = NULL
AS
BEGIN
	SET NOCOUNT ON;
	SET DATEFIRST 1;

	SELECT SUM(CntVisitors) AS CntVisitors, YEAR(CurrentDate) AS CurrentYear, CurrentMonth=0, 
		CurrentWeek = DATEPART(WW,CurrentDate), CurrentDay=0
	FROM vw_Stat_UniqueVisitors
	WHERE (CurrentDate BETWEEN @StartDate AND @EndDate)
	GROUP BY YEAR(CurrentDate), DATEPART(WW,CurrentDate)
	ORDER BY YEAR(CurrentDate), DATEPART(WW,CurrentDate)
END

Får detta resultat:

[Stat_GetWeekUniqueVisitors] '2007-12-10', '2008-01-06'

12	2007	0	52	0
3	2007	0	53	0
19	2008	0	1	0

Jag får alltså 3 st vecka 53, 2007 samt 19 st v. 1, 2008 men detta är samma vecka så de borde mao. slås ihop! Går det att stuva om koden så att den summerar veckorna rätt?

(ms sql 2005)

Medlem sedan dec. 20025 483 inlägg
#2

Du får omvandla till ISO-veckor:

http://www.tek-tips.com/viewthread.cfm?qid=1244574&page=1 skrev:

CREATE FUNCTION ISOWeek (@TheDate smalldatetime)
RETURNS int
AS
BEGIN
   DECLARE @D int, @D2 int
   SET @D = Convert(int, DateAdd(dd, DateDiff(dd, 0, @TheDate), 0))
   SET @D = @D - @D % 7 + 3
   SET @D2 = Convert(int, DateAdd(yy, DateDiff(yy, 0, DateAdd(dd, @D, 0)), 0))
   SET @D2 = @D2 + 6 - (@D2 - 4) % 7
   RETURN (@D - @D2) / 7 + 1
END
Medlem sedan juni 20003 076 inlägg
#3

Njae, så hade jag först men det håller tyvärr inte (eller?) eftersom att startdatum kan vara ex. 1:a veckan 2007 och slutdatum kan vara 3:e veckan 2008.
Det innebär att det finns 2 st vecka 1, både 2007 samt 2008 och dessa får inte slås ihop.
En snabb (ful) fix kan se ut så här:

ALTER PROCEDURE [dbo].[Stat_GetWeekUniqueVisitors]
	@StartDate datetime = NULL,
	@EndDate datetime = NULL
AS
BEGIN
	SET NOCOUNT ON;
	SET DATEFIRST 1;

	WITH CTE_Weeks AS (
		SELECT SUM(CntVisitors) AS CntVisitors, 
			CASE DATEPART(WW,CurrentDate) WHEN 53 THEN
				 YEAR(CurrentDate)+1 
				ELSE 
					YEAR(CurrentDate) END AS CurrentYear, 
			CurrentMonth=0, 
			CASE DATEPART(WW,CurrentDate) WHEN 53 THEN
				1 
			ELSE 
				DATEPART(WW,CurrentDate) END AS CurrentWeek,
			CurrentDay=0
		FROM vw_Stat_UniqueVisitors
		WHERE (CurrentDate BETWEEN @StartDate AND @EndDate)
		GROUP BY YEAR(CurrentDate), DATEPART(WW,CurrentDate)
	)

	SELECT SUM(CntVisitors), CurrentYear, CurrentMonth, CurrentWeek, CurrentDay
	FROM CTE_Weeks
	GROUP BY CurrentYear, CurrentMonth, CurrentWeek, CurrentDay
	ORDER BY CurrentYear, CurrentWeek
	
END

Jag vet inte om den kommer att funka på alla sorters datum men den funkar på ovanstående i alla fall! Men snyggt? Nää!

Medlem sedan dec. 20025 483 inlägg
#4

Nu hänger jag inte med. Varför fungerar inte:

ALTER PROCEDURE [dbo].[Stat_GetWeekUniqueVisitors]
	@StartDate datetime = NULL,
	@EndDate datetime = NULL
AS
BEGIN
	SET NOCOUNT ON;
	SET DATEFIRST 1;

	SELECT SUM(CntVisitors) AS CntVisitors, YEAR(CurrentDate) AS CurrentYear, CurrentMonth=0, 
		CurrentWeek = ISOWeek(CurrentDate), CurrentDay=0
	FROM vw_Stat_UniqueVisitors
	WHERE (CurrentDate BETWEEN @StartDate AND @EndDate)
	GROUP BY YEAR(CurrentDate), ISOWeek(CurrentDate)
	ORDER BY YEAR(CurrentDate), ISOWeek(CurrentDate)
END

?

Medlem sedan juni 20003 076 inlägg
#5

Därför! ;)
Resultatet blir i ditt fall så här:

3	2007	0	1	0
12	2007	0	52	0
19	2008	0	1	0

Och det är fel eftersom det inte finns några besök alls v1. 2007.
Korrekt resultatet ska bli så här:

12	2007	0	52	0
22	2008	0	1	0

Eftersom flera år kan hämtas så kan jag inte bara köra isoweek på veckorna eftersom det grupperas årsvis också!

Medlem sedan dec. 200012 464 inlägg
#6

Du får väl göra en isoyear-funktion som patchar om året till nästa om isoweek blir 1 för ett datum i december.

263 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
121 ms — deklarationer (db)
0 ms — hämta statistik (cache)
138 ms — hämta tråd, inlägg och bilagor (db)
122 ms — ändringar (db)