Hur gör jag en jämförelse mellan innevarande vecka -4 och en vecka (int) i databasen som är skriven som 200801 till 200852, helst svensk veckonumrering. I VB är det en barnlek men jag är usel på transact sql så... Kan du beskriva lite mer. Jag vill göra en select-sats som bara visar poster där veckan i databasen är <= innevarande vecka minus 4 veckor. Du skulle kunna göra t.ex så här: Så dom poster som du ska hämta upp från databasen Ger ett exempel innan du svarat på min föregående fråga. Tack Samuel och Håkan, kolumnen i databasen är integer (int) som jag försökte beskriva i mitt första inlägg så jag tror Samuels lösning passar bäst. Kör "SELECT @@DATEFIRST" så får du till baka vilken dag som databasen betraktar som veckans första. Tyvärr så kommer nog inte Samuels lösning att ge rätt vecka. Här är en lösning som ger dig svar 53 för 2005-01-01. Jag har utgått från en C# metod som jag hittade för något år sen på webben och som jag har använt av och till för just det här, men hittar tyvärr ingen länk till den nu. Du kan få kodsnutten här på forumet om du vill det. Mmmmm... Håkan, jag får en förskjutning med din ISOweek så du har nog rätt i att det beror på vilken inställning databsen har. Ja den bygger på att du har första dagen i veckan på måndag (som nämts tidigare) som vi har i Sverige. [Samuel] LUT = Look Up Table, uttrycket används väl egentligen inte i databassammanhang. Ok.Banal datum/veckofråga ?
Sv: Banal datum/veckofråga ?
Är inte säker på vad du vill få ut. (utdata).
Hur ser det ut som du lagrat i databasen.
Vad betyder det här? "innevarande vecka -4" (Vad är -4).
Finns det någon indata eller är det statiskt?Sv:Banal datum/veckofråga ?
Innevarande vecka -4 menar jag alltså fyra veckor innan nuvarande vecka (vecka 47 nu, 47-4=43 alltså vecka 43). Således, visa bara veckor <= v 43.
I databasen ligger veckan som 200801 för vecka 1 år 2008 etc.
Mitt problem är att skapa en giltig (svensk) vecka av getdate() på formatet yyyyww (och inte 20081 utan 200801 om det skulle vara vecka 1). Alternativt att skapa ett datum från databasens vecka som kan jämföras med getdate().Sv: Banal datum/veckofråga ?
DECLARE @yw INT
DECLARE @date DATETIME
SET @date = GETDATE()
SET @yw = DATEPART(yyyy, @date) * 100 + DATEPART(wk, @date)
SELECT CAST (@yw AS VARCHAR(6))Sv: Banal datum/veckofråga ?
och jämföra veckan mot har formatet 200801 för vecka 1.
De är då lagrade som strängar?Sv: Banal datum/veckofråga ?
Förutsätter att du lagrat "veckodatat" (200801) som sträng.
<code>
SELECT *
FROM [min tabell]
WHERE (CAST(RIGHT([min veckokolumn], 2) AS int) = (DATEPART(ww, GETDATE()) - 4))
</code>Sv:Banal datum/veckofråga ?
Jag har inte fattat riktigt hur DATEPART(ww, GETDATE()) funkar med svensk veckoräkning (måndag = 1:a dag i veckan, 1:a vecka med mer är 3 dagar på året = vecka 1)
Det är ju genant att vara så usel på transact-sql när man har svart bälte i VB & VBA...Sv: Banal datum/veckofråga ?
1 Monday
2 Tuesday
3 Wednesday
4 Thursday
5 Friday
6 Saturday
7 (default, U.S. English) Sunday
Vill du ändra detta skriver du t.ex. SET DATEFIRST 1 (Nu är måndag första dagen i veckan) Sv: Banal datum/veckofråga ?
testa att skriva in 2005-01-01 det ger 200501 men borde ge 200553.
Det du funderar på är "ISO veckor".
Och nej det kommer att bli fel om du t.ex kör SELECT DATEPART(ww, '2005-01-01');
så får du 1 men borde få 53. Sv:Banal datum/veckofråga ?
Här är sql-funktionen:
---- start
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
CREATE FUNCTION FindWeekNumber (@Date datetime)
RETURNS int
AS
BEGIN
DECLARE @THURSDAY INT
DECLARE @ThursdayFlag BIT
DECLARE @DayOfYear INT
SET @THURSDAY =4
SET @ThursdayFlag = 0
SET @DayOfYear = DATEPART(dayofyear,@Date)
DECLARE @DateYear INT
SET @DateYear = DATEPART(yyyy, @Date)
DECLARE @FirstDateOfCurrYear datetime
DECLARE @LastDateOfCurrYear datetime
SET @FirstDateOfCurrYear = CAST(@DateYear AS VARCHAR(10)) + '-01-01'
SET @LastDateOfCurrYear = CAST(@DateYear AS VARCHAR(10)) + '-12-31'
DECLARE @StartWeekDayOfYear INT
DECLARE @EndWeekDayOfYear INT
DECLARE @DaysInFirstWeek INT
DECLARE @DaysInLastWeek INT
SET @StartWeekDayOfYear = DATEPART(dw, @FirstDateOfCurrYear)
SET @EndWeekDayOfYear = DATEPART(dw, @LastDateOfCurrYear)
IF @StartWeekDayOfYear > 1 -- Om icke söndag
BEGIN
SET @StartWeekDayOfYear = @StartWeekDayOfYear - 1
END
ELSE -- annars om söndag
BEGIN
SET @StartWeekDayOfYear = 7
END
IF @EndWeekDayOfYear > 1 -- Om icke söndag
BEGIN
SET @EndWeekDayOfYear = @EndWeekDayOfYear - 1
END
ELSE -- annars om söndag
BEGIN
SET @EndWeekDayOfYear = 7
END
SET @DaysInFirstWeek = 8 - (@StartWeekDayOfYear );
SET @DaysInLastWeek = 8 - (@EndWeekDayOfYear );
IF @StartWeekDayOfYear = @THURSDAY OR @EndWeekDayOfYear = @THURSDAY
BEGIN
SET @ThursdayFlag = 1
END
DECLARE @FullWeeks INT
DECLARE @WeekNumber INT
SET @FullWeeks = CEILING( (@DayOfYear - @DaysInFirstWeek) / 7.0)
SET @WeekNumber = @FullWeeks
IF @DaysInFirstWeek >= @THURSDAY
BEGIN
SET @WeekNumber = @WeekNumber + 1
END
IF @WeekNumber > 52 AND @ThursdayFlag = 0
BEGIN
SET @WeekNumber = 1
END
IF @WeekNumber = 0
BEGIN
DECLARE @NewDate DATETIME
SET @NewDate = CAST(DATEPART(yyyy, @Date)-1 AS VARCHAR(10)) + '-12-31'
SET @WeekNumber = dbo.FindWeekNumber(@NewDate)
END
return @WeekNumber;
END
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
---- slutSv: Banal datum/veckofråga ?
Din funktion bygger på att första dagen är Söndag (7), vilket är default för USA bla.
Har man ställt in databasen på svenska (ger måndag som första dag),
eller satt att första dagen är måndag specifikt så ger din funktion en förskjutning.
2004-12-27 ger vecka 52 men borde ge 53, 2005-01-03 ger 53 men borde ge 1.
ISO veckor bygger på att måndag är första dagen.
Här är en (kortare) funktion som utgår från att måndag är första veckan.
<code>
CREATE FUNCTION dbo.ISOweek (@DATE DATETIME)
RETURNS int
WITH EXECUTE AS CALLER
AS
BEGIN
DECLARE @ISOweek int
SET @ISOweek= DATEPART(wk,@DATE)+1
-DATEPART(wk,CAST(DATEPART(yy,@DATE) as CHAR(4))+'0104')
--Special cases: Jan 1-3 may belong to the previous year
IF (@ISOweek=0)
SET @ISOweek=dbo.ISOweek(CAST(DATEPART(yy,@DATE)-1
AS CHAR(4))+'12'+ CAST(24+DATEPART(DAY,@DATE) AS CHAR(2)))+1
--Special case: Dec 29-31 may belong to the next year
IF ((DATEPART(mm,@DATE)=12) AND
((DATEPART(dd,@DATE)-DATEPART(dw,@DATE))>= 28))
SET @ISOweek=1
RETURN(@ISOweek)
END;
GO
</code>Sv:Banal datum/veckofråga ?
Men iaf, ett bättre sätt än att räkna ut veckonummer för varje gång borde ju vara att ha en lut-tabell (förifylld x år framåt och bakåt) med mappning mellan datumintervall och veckor. T.ex
StartDate -- datetime
EndDate -- datetime
WeekNumber -- int WW
YearWeekNumber -- int YYYYWW
Då är det ju bara göra en join med den tabellen i själva frågan.Sv: Banal datum/veckofråga ?
Den som Christer frågade efter.
Du har antagligen Engelska (7).
För att den ska fungera så ska databsen vara satt till antingen Svenska eller DATEFIRST till 1.
Alltså SET LANGUAGE Svenska; eller SET DATEFIRST 1;
Vill du veta vad du har kör SELECT @@DATEFIRST;Sv: Banal datum/veckofråga ?
Ursäkta svarade bara lite mekaniskt på det första du skrev.
Njaa kanske inte i det här fallet, men jag vet för lite hur det är tänkt att avända.
Känslan jag får är att det är en stående fråga (rapport/statistik), och att det som han efterfrågar är ett sätt att få ut dels rätt vecka (svensk) hänga på året (tillkrånglat enligt mig iaf),
och sedan att t.ex via en variabel jämföra den mot årveckokolumnen i WHERE/JOIN.
(Lite som en permanet inparameter).
Vilket kommer att vara helt ok frågemässigt.
Annars så tycker jag att lagringsformatet är tillkrånglat, vill du åt veckan spara den separat i varje post.
[SET OFFTOPIC ON]
När man använder funktioner för att plocka ut data så använder inte frågeoptimeraren index,
utan skannar hela tabellen (gäller troligtvis inte i det här fallet, se ovan).
[SET OFFTOPIC OFF]
Kan du förklara uttrycket lut-tabell, har aldrig stött på det förut.
(alltså inte vad det du skrev ovan ska göra utan uttrycket).
Ja ja... lite mer svammel en lördagskväll... :-)Sv:Banal datum/veckofråga ?
Sv: Banal datum/veckofråga ?
Tack för infon.
Jo just det det används, men har då bara sett lookup table inte lut.
Men man lär sig något nytt varje dag.