Wybieranie 4 ostatnich tygodni... w SQL

0

Witam,
Poproszę Was o pomoc jak pogryźć temat :-).
Muszę dopracować zapytanie w SQL (SQL Serwer 2008).

Zapytanie SUMUJE rekordy wydań z magazynu z przesunięciem tygodni:
Indeks
Nazwa
SUM ILOŚĆ_BIEŻĄCY
0 T-1
0 T-2
0 T-3
0 T-4
UNION
Indeks
Nazwa
0 ILOŚĆ_BIEŻĄCY
0 SUMA T-1
0 T-2
0 T-3
0 T-4
UNION
Indeks
Nazwa
0 ILOŚĆ_BIEŻĄCY
0 T-1
0 SUMA T-2
0 T-3
0 T-4
(...) itd do końca z przesunięciem do T-4.
Następnie.
Sumuję następnie Wszystkie KOLUMNY aby "skasować" ZERA i wyrównać tabelę.

W wyniku tego mam ładną tabelę (w uproszczeniu):
Indeks Nazwa TB T-1 T-2 T-3 T-4

Numer tygodnia do sumowania tygodniowego pobieram z daty wydania z magazynu DD-MM-RRRR.
Ten numer tygodnia porównuję do obecnego numeru tygodnia (z daty obecnej).

  • Sprawdzam numer bieżącego tygodnia.
    i pokazuję dane sumując według tygodni:
    Tydzień -4: Bieżący numer tygodnia -4
    Tydzień -3: Bieżący numer tygodnia -3
    Tydzień -2: Bieżący numer tygodnia -2
    Tydzień -1: Bieżący numer tygodnia -1
    Tydzień BIEŻĄCY: Bieżący numer tygodnia
    Wszystko ładnie działa.
    **
    Ale nie mam koncepcji jak podejść do "Początku roku".**
    DATA BIEŻĄCA zwraca - Tydzień 1/2017:
    Tydzień -4: Bieżący numer tygodnia 49/2016
    Tydzień -3: Bieżący numer tygodnia 50/2016
    Tydzień -2: Bieżący numer tygodnia 51/2016
    Tydzień -1: Bieżący numer tygodnia 52/2016
    Tydzień BIEŻĄCY: Bieżący numer tygodnia 1/2017
    Tutaj nie ma problemu: Mogę zadeklarować zmienną @MSC przypisując do niej:
    T-1 to 52 rok 2016
    T-2 to 51 rok 2016
    T-3 to 50 rok 2016
    T-4 to 49 rok 2016

Problem zaczyna się od "2" tygodnia gdzie mamy przeskok tygodni i roku.
DATA BIEŻĄCA zwraca - Tydzień 2/2017:
Tydzień -4: Bieżący numer tygodnia 41/2016
Tydzień -3: Bieżący numer tygodnia 51/2016
Tydzień -2: Bieżący numer tygodnia 52/2016
Tydzień -1: Bieżący numer tygodnia 2/2017
Tydzień BIEŻĄCY: Bieżący numer tygodnia 2/2017

DATA BIEŻĄCA zwraca - Tydzień 3/2017:
Tydzień -4: Bieżący numer tygodnia 51/2016
Tydzień -3: Bieżący numer tygodnia 52/2016
Tydzień -2: Bieżący numer tygodnia 1/2017
Tydzień -1: Bieżący numer tygodnia 2/2017
Tydzień BIEŻĄCY: Bieżący numer tygodnia 3/2017

(...) i tak dalej.
Problem się kończy w tygodniu 5 bo dla niego tydzień pierwszy jest bez problemu do pobrania piąty tydzień 5- tydzień 4 = tydzień 1.

Ma Ktoś z Was jakiś pomysł jak to zrobić?

0

w ogóle nie zrozumiałem w czym problem.
A co do wybierania danych to ja bym to inaczej zrobił

select
  nazwa,
  indeks,
  sum(ilosc) ilosc,
  DATEPART(year, data_wydania) rok,
  DATEPART(week, data_wydania) tydzien
from
  tabela
where
  DATEPART(year, data_wydania) =   DATEPART(year, GETDATE())
  and   DATEPART(week, data_wydania) >=   DATEPART(year, GETDATE()) - 4
order by
  4, 5

do tego odpowiednie indeksy i będzie śmigać. Jedno zapytanie, możesz regulować zakres jak chcesz, przełom roku nie jest problemem. A i zrobienie z tego crosstaba czy to przy użyciu pivot czy case when to dodatkowe parę linijek

1

Moim zdaniem niepotrzebnie operujesz na tygodniach, skoro spokojnie, możesz poznać daty całego okresu, rozumiem, że chodzi o tydzień, dla daty dzisiejszej:
2016-10-16 to zakres dat: 2017-09-18 - 2017-10-22

zwróć uwagę na SET DATEFIRST 1 chodzi o to, żeby poniedziałek był pierwszym dnie tygodnia

Czyli where budujesz na podstawie SQL:

/*
pobranie daty końca tygodnia można zrealizować takim zapisem
DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())
początek okresu to odjęcie od wyliczonej daty 34 dni
DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())-34
*/
SET DATEFIRST 1
select * from tabela
where data between DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())-34 and DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())

Reszta to policzenie, który tydzień. Wystarczy podzielić różnicę w dniach pomiędzy datą w tabeli i datą końca weekendu przez 7, część całkowita pokazuje czy tydzień bieżący, czy nie. Teraz tylko pokazać wynik:

SET DATEFIRST 1
select 
  indeks
  ,sum(case when datediff(dd,data,DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())) / 7 = 0 then ilosc else 0 end) TB
  ,sum(case when datediff(dd,data,DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())) / 7 = 1 then ilosc else 0 end) [T-1]
  ,sum(case when datediff(dd,data,DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())) / 7 = 2 then ilosc else 0 end) [T-2]
  ,sum(case when datediff(dd,data,DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())) / 7 = 3 then ilosc else 0 end) [T-3]
  ,sum(case when datediff(dd,data,DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())) / 7 = 4 then ilosc else 0 end) [T-4]
from
  tab
where 
    data between DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())-34
and DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())
group by
   indeks

Fiddle: http://sqlfiddle.com/#!6/4abf1/5

0

Tygodnie niestety muszą być :-( i musi to być przypisane na sztywno tak jak pokazuje nasz system główny.
I dzisiaj o 5.00 wymyśliłem jak to zrobić.

Podam w skrócie ideę pomysłu bo Oryginał ma ponad 300 linijek, więc wrzucę tylko fragment który działa, ale pokazuje rozwiązanie problemu.

Tworzę zmienne przyporządkowane do okresów, czyli mogę sztucznie wygenerować zmiany na początku roku zależne od:

  • Tygodnie (dla każdego oddzielna zmienna)
  • Miesiąca
    Należy wygenerować zmiennymi następujący układ:

Tydzień 1 Tydzień 2 Tydzień 3 Tydzień 4 - tygodnie bieżące.
52/2016 1/2017 1/2017 1/2017
51/2016 52/2016 2/2017 2/2017
50/2016 51/2016 52/2016 3/2017
49/2016 50/2016 51/2016 52/2016

SET @TYDZ_1 = (CASE
WHEN (DATEPART (WW, GETDATE())) = 1 THEN 52
WHEN (DATEPART (WW, GETDATE())) = 2 THEN 1
WHEN (DATEPART (WW, GETDATE())) = 3 THEN 2
WHEN (DATEPART (WW, GETDATE())) = 4 THEN 3
ELSE (DATEPART (WW, GETDATE())) -1
END);
SET @TYDZ_2 = (CASE
WHEN (DATEPART (WW, GETDATE())) = 1 THEN 51
WHEN (DATEPART (WW, GETDATE())) = 2 THEN 52
WHEN (DATEPART (WW, GETDATE())) = 3 THEN 1
WHEN (DATEPART (WW, GETDATE())) = 4 THEN 2
ELSE (DATEPART (WW, GETDATE())) -2
END);
SET @TYDZ_3 = (CASE
WHEN (DATEPART (WW, GETDATE())) = 1 THEN 50
WHEN (DATEPART (WW, GETDATE())) = 2 THEN 51
WHEN (DATEPART (WW, GETDATE())) = 3 THEN 52
WHEN (DATEPART (WW, GETDATE())) = 4 THEN 1
ELSE (DATEPART (WW, GETDATE())) -3
END);
SET @TYDZ_4 = (CASE
WHEN (DATEPART (WW, GETDATE())) = 1 THEN 49
WHEN (DATEPART (WW, GETDATE())) = 2 THEN 50
WHEN (DATEPART (WW, GETDATE())) = 3 THEN 51
WHEN (DATEPART (WW, GETDATE())) = 4 THEN 52
ELSE (DATEPART (WW, GETDATE())) -4
END);

Założenie to bezobsługowe działanie, jak najbardziej "idioto odporne".
Docelowo całość będzie wrzucona na Reporting Service gdzie obsługa ograniczy się do uruchom.

DECLARE @TYDZ_POP INT;
DECLARE @ROK_TYDZ_POP INT;

SET @TYDZ_POP = (CASE
WHEN (DATEPART (WW, GETDATE())) = 1 THEN 52
ELSE (DATEPART (WW, GETDATE())) -1
END);

SET @ROK_TYDZ_POP = (CASE
WHEN (DATEPART (WW, GETDATE())) = 1 THEN 2016
ELSE (DATEPART (YYYY, GETDATE()))
END);

SELECT
V_ZAMOWIENIA_REALIZACJA_STATUS.TWR_NUMER,
V_ZAMOWIENIA_REALIZACJA_STATUS.TWR_NAZWA,
0 AS DZISIAJ,
0 AS WCZORAJ,
0 AS TYDZ_BIEZ,
0 AS MSC_BIEZ,
Sum(V_ZAMOWIENIA_REALIZACJA_STATUS.ZMWDT_ILOSC_REAL) AS TYDZ_POPRZ,
0 AS MSC_POPRZ,
dbo.VRP_TOWARY_FULL.TWR_GRUPA_TECHNOLOGICZNA,
dbo.VRP_TOWARY_FULL.TWR_GRUPA_ZAMOWIEN,
V_ZAMOWIENIA_REALIZACJA_STATUS.SLJM_KOD
FROM
V_ZAMOWIENIA_REALIZACJA_STATUS
INNER JOIN dbo.VRP_TOWARY_FULL ON (V_ZAMOWIENIA_REALIZACJA_STATUS.TWR_NUMER = dbo.VRP_TOWARY_FULL.TWR_NUMER)
WHERE
** DATEPART (WW, (V_ZAMOWIENIA_REALIZACJA_STATUS.ZMW_DATA_ZAMOWIENIA)) = (@TYDZ_POP) AND
DATEPART (YYYY, (V_ZAMOWIENIA_REALIZACJA_STATUS.ZMW_DATA_ZAMOWIENIA)) = (@ROK_TYDZ_POP)**

GROUP BY
V_ZAMOWIENIA_REALIZACJA_STATUS.TWR_NUMER,
V_ZAMOWIENIA_REALIZACJA_STATUS.TWR_NAZWA,
dbo.VRP_TOWARY_FULL.TWR_GRUPA_TECHNOLOGICZNA,
dbo.VRP_TOWARY_FULL.TWR_GRUPA_ZAMOWIEN,
V_ZAMOWIENIA_REALIZACJA_STATUS.SLJM_KOD
HAVING
Sum(V_ZAMOWIENIA_REALIZACJA_STATUS.ZMWDT_ILOSC_REAL) <> 0

0

Raport daje coś takiego:

Indeks Nazwa T-4 T-3 T-2 T-1 TB
1 Produkt 1 200 180 190 200 50
2 Produkt 2 150 160 170 200 60

Gdzie:
TB - aktualny numer tygodnia (Teraz 42).
T-1 - 41
T-2 - 40
T-3 - 39
T-4 - 38
Gdy tydzień bieżący zmieni się na 43 to numery poprzednich tygodni +1.
Problem jest zawsze w styczniu :-)
W ciągu roku można dla tygodnia >= "5" stosować: (DATEPART (WW, GETDATE())) - 4
Gdzie: -4 to ilość tygodni do odjęcia od bieżącego: -1, -2, -3, -4 :-)

0

Pivot

0

Nie zrozumiałeś mojego posta, pisząc żeby nie używać tygodni miałem na myśli to żeby operować na datach anie na tygodniach i funkcji datepart,
Przecież jeżeli dzisiejszy tydzień kończy się 22 października to wiadomo że poniedziełek 5 tygodni temu był 35 dni temu (5x7) czyli 18 Września 2017.
I sprawdźmy co z tym można zrobić

SET DATEFIRST 1
declare @dEnd datetime
declare @dStart datetime
select
  @dEnd=DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())
  ,@dStart=DATEADD(dd, 7-(DATEPART(dw, getdate())), getdate())-34
Select @dStart, @dEnd

wynik:
2017-09-18 2017-10-22

I teraz zobacz pewną prawidłowość

Data Datepart(dw,data) datediff(dd,data,@dEnd) datediff(dd,data,@dEnd)/7
2017-10-22 43 0 0
2017-10-21 43 1 0
2017-10-20 43 2 0
2017-10-19 43 3 0
2017-10-18 43 4 0
2017-10-17 43 5 0
2017-10-16 43 6 0
2017-10-15 42 7 1
2017-10-14 42 8 1
2017-10-13 42 9 1
2017-10-12 42 10 1
2017-10-11 42 11 1
2017-10-10 42 12 1
2017-10-09 42 13 1
2017-10-08 41 14 2
2017-10-07 41 15 2
2017-10-06 41 16 2
2017-10-05 41 17 2
2017-10-04 41 18 2
2017-10-03 41 19 2
2017-10-02 41 20 2
2017-10-01 40 21 3
2017-09-30 40 22 3
2017-09-29 40 23 3
2017-09-28 40 24 3
2017-09-27 40 25 3
2017-09-26 40 26 3
2017-09-25 40 27 3
2017-09-24 39 28 4
2017-09-23 39 29 4
2017-09-22 39 30 4
2017-09-21 39 31 4
2017-09-20 39 32 4
2017-09-19 39 33 4
2017-09-18 39 34 4

Ostatnia kolumna to klucz do zrozumienia tego co opisałem:

SET DATEFIRST 1   
--celowo deklaruje zmienną, aby nie używać getdate i pokazać 
--działanie na przełomie roku
Declare @getdate as datetime
declare @dEnd datetime
declare @dStart datetime
set @getdate='2017-01-07'

select
  @dEnd=DATEADD(dd, 7-(DATEPART(dw, @getdate)), @getdate)
  ,@dStart=DATEADD(dd, 7-(DATEPART(dw, @getdate)), @getdate)-34
  
 select 
  indeks
  ,sum(case when datediff(dd,data,@dEnd) / 7 = 0 then ilosc else 0 end) TB
  ,sum(case when datediff(dd,data,@dEnd) / 7 = 1 then ilosc else 0 end) [T-1]
  ,sum(case when datediff(dd,data,@dEnd) / 7 = 2 then ilosc else 0 end) [T-2]
  ,sum(case when datediff(dd,data,@dEnd) / 7 = 3 then ilosc else 0 end) [T-3]
  ,sum(case when datediff(dd,data,@dEnd) / 7 = 4 then ilosc else 0 end) [T-4]
from
  tab
where 
    data between @dStart and @dEnd
group by
   indeks

http://sqlfiddle.com/#!6/4abf1/12

Nie trzeba dodatkowej magi w zmiennych tygodniach, zadziała dla dowolnej daty.

0
abrakadaber napisał(a):

w ogóle nie zrozumiałem w czym problem.
A co do wybierania danych to ja bym to inaczej zrobił

select
  nazwa,
  indeks,
  sum(ilosc) ilosc,
  DATEPART(year, data_wydania) rok,
  DATEPART(week, data_wydania) tydzien
from
  tabela
where
  DATEPART(year, data_wydania) =   DATEPART(year, GETDATE())
  and   DATEPART(week, data_wydania) >=   DATEPART(year, GETDATE()) - 4
order by
  4, 5

do tego odpowiednie indeksy i będzie śmigać. Jedno zapytanie, możesz regulować zakres jak chcesz, przełom roku nie jest problemem. A i zrobienie z tego crosstaba czy to przy użyciu pivot czy case when to dodatkowe parę linijek

DATEPART(year, data_wydania) = DATEPART(year, GETDATE())
Rok z daty wydania 2016 - a obecnie masz styczeń i 2017 i co dalej?
Podobny kod mam obecnie, i muszę go poprawić na "Styczeń" gdzie masz przeskok ROKU i TYGODNI.

0

masz odpowiedź w komentarzu pod tamtym postem Wybieranie 4 ostatnich tygodni... w SQL
Ale jeszcze raz - poprawnie powinno być tak

SELECT
  nazwa,
  indeks,
  SUM(ilosc) ilosc,
  DATEPART(YEAR, data_wydania) rok,
  DATEPART(week, data_wydania) tydzien
FROM
  tabela
WHERE
  data_wydania >= DATEADD(dd, -(DATEPART(dw, DATEADD(week, -4, GETDATE()))-1), DATEADD(week, -4, GETDATE()))
GROUP BY
  nazwa,
  indeks,
  DATEPART(YEAR, data_wydania),
  DATEPART(week, data_wydania)
ORDER BY           
  4, 5

masz wybrane wszystkie dane od 4 pełnych tygodni wstecz do dzisiaj, czyli dla dnia dzisiejszego dostaniesz dane od 2017-09-17 do 2017-10-17 co odpowiada

data od | data do | T | rok | tydzień
---------------- | -------------------
2017-09-18 | 2017-09-24 | T-4 | 2017 | 38
2017-09-25 | 2017-10-01 | T-3 | 2017 | 39
2017-10-02 | 2017-10-08 | T-2 | 2017 | 40
2017-10-09 | 2017-10-15 | T-1 | 2017 | 41
2017-10-16 | 2017-10-17 | T0 | 2017 | 42

pogrupowane po nazwie, indeksie, roku i tygodniu. Nic tylko zrobić z tego jeszcze pivota i po zawodach. Bez kombinowania, obliczania przedziałów, unionów (WTF?) i innych pierdół. Proste zapytanie, gdzie w warunku masz tylko jedno porównanie (jakbyś chciał ograniczyć datę do dzisiaj to dwa).
Tylko trzeba ustawić DATEFIRST najpierw

0

Dziękuję za Waszą pomoc.
Jutro przetestuję to na serwerze. Zaczyna to mieć "ręce i nogi" bez kombinowania.
I bardzo duży szacun od Waszej wiedzy.

0

@abrakadaber:

To nie jest takie oczywiste jak to opisałeś, rozpatrzmy to dla daty 2017-01-01 tj. niedziela, domyślnie DATEFIRST jest 7 w twoim warunku:

--domyślne ustawienie SQL Server
set datefirst 7
select
DATEADD(dd, -(DATEPART(dw, DATEADD(week, -4, '2017-01-01'))-1), DATEADD(week, -4, '2017-01-01'))

Zwraca 2016-12-04, wiadomo liczymy dla założenia, że poniedziałek jest pierwszym tygodniem:

set datefirst 1
select
DATEADD(dd, -(DATEPART(dw, DATEADD(week, -4, '2017-01-01'))-1), DATEADD(week, -4, '2017-01-01'))

Zwraca 28-11-2017 czyli ok, teraz taka uwaga: działanie datepart z argumentem week:

data datepart(week,data) datepart(iso_week,data)
2017-01-01 1 52
2016-12-31 53 52
2016-12-30 53 52
2016-12-29 53 52
2016-12-28 53 52
2016-12-27 53 52
2016-12-26 53 52
2016-12-25 52 51
2016-12-24 52 51
2016-12-23 52 51
2016-12-22 52 51
2016-12-21 52 51
2016-12-20 52 51

I teraz, twoje rozwiązanie zwróci 6 "tygodni": 1,49,50,51,52,53 co już zaburza nam raport, przy okazji pokazuje błąd w rozumowaniu @Ciapek, który założył, ze datepart week zwróci mu maksymalnie 52. ISO_WEEK zwraca poprawną ilość tygodni: 48,49,50,51,52, ale już datepart year dla 1.1.2017 to 2017 czyli "po złaczeniu": 52 tydzień 2017 roku...

Dlatego napiszę jeszcze raz nie ma znaczenia w tym zadaniu który to jest tydzień roku, tylko przedział bieżącego tygodnia + 4 ostatnie, oczywiście możemy "bawić się" w zmuszanie SQL do działania konkretnie pod rozwiązanie, kiedy to jest para w gwizdek...

0

Panowie,
bardzo dziękuję za Pomoc. Wszytko działa :-).
Zastosowałem rozwiązania Kolegi: @abrakadaber. oraz dzięki Waszemu ukierunkowaniu, poszukałem w internecie i znalazłem:
I dochodzę do wniosku, że daty w SQL doprowadzają mnie do...

DATEADD(MONTH, DATEDIFF(MONTH, 0, getdate()) - 1, 0), -- Pierwszy dzień poprzedni miesiąc, -1 na inną cyfrę cofamy się np: (2 - dwa miesiące)
DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()) - 1, 0), -- Pierwszy dzień poprzedni tydzień, zmieniając -1 na inne cofamy się np: (2 - dwa tygodnie)

DATEADD (dd,-DAY(GETDATE()), GETDATE()), -- Ostatni dzień poprzedni miesiąc
DATEADD (dd,-DAY(GETDATE()-1 ), GETDATE()) -- Pierwszy dzień obecnego miesiąca

Chciałbym Wasze rozwiązanie dalej wprowadzać, ale nie udało mi się znaleźć:
-- Ostatni dzień poprzedni tydzień
-- Ostatni dzień dowolny tydzień
-- Ostatni dzień dowolny miesiąc
Możecie pomóc?

Przy okazji mam pytanie, teoretyczne...
Ostatni dzień poprzedni miesiąc zwraca: 30.09.2017 1844
Czy rekordy po godzinie: 1844 będą pokazane?
Czy należy zrobić Convert dla pola daty?

Dalej staram się "przekopać przez daty"....
-- Ostatni dzień poprzedni tydzień:
DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()) - 0, 0) -1.
Czy to rozwiązanie jest poprawne?

0

ostatni dzień miesiąca https://msdn.microsoft.com/pl-pl/library/hh213020(v=sql.110).aspx
ostatni i pierwszy dzień tygodnia https://stackoverflow.com/questions/21330671/how-to-get-first-day-of-the-week-and-last-day-of-the-week-in-sql-server-2008
jako datę możesz podać np cast('20171001' as date)

Ostatni dzień poprzedni miesiąc zwraca: 30.09.2017 1844
Czy rekordy po godzinie: 1844 będą pokazane?

zależy jaki dasz warunek

Czy należy zrobić Convert dla pola daty?

zależy po co

0

Zrobiłem coś takiego:
SET DATEFIRST 1 -- Pierwszy dzień tygodnia - PONIEDZIAŁEK.

DECLARE @Today Date; -- Dzisiaj
DECLARE @Yesterday Date; -- Wczoraj
DECLARE @dStartWeek Date; -- Początek obecnego tygodnia
DECLARE @dEndWeek Date; -- Koniec obecnego tygodnia
DECLARE @dStartWeekPrevious Date; -- Początek poprzedniego tygodnia
DECLARE @dEndWeekPrevious Date; -- Koniec poprzedniego tygodnia
DECLARE @dStartMonth Date; -- Początek obecnego miesiąca
DECLARE @dStartMonthPrevious Date; -- Początek poprzedniego miesiąca
DECLARE @dEndMonthPrevious Date; -- Koniec poprzedniego miesiąca
DECLARE @dStartWycofania Date; -- Data przekazań towaru

SET @Today = CONVERT (DATE, GETDATE (), 104);
SET @Yesterday = CONVERT (DATE, GETDATE ()-1, 104);
SET @dStartWeek = DATEADD(wk, DATEDIFF(dd, 0, GETDATE()) / 7, 0);
SET @dEndWeek = GETDATE() + (7 - DATEPART(dw, GETDATE()));
SET @dStartWeekPrevious = DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()) - 1, 0);
SET @dEndWeekPrevious = DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()) -0, 0) - 1;
SET @dStartMonth = DATEADD (dd,-DAY(GETDATE()-1 ), GETDATE());
SET @dStartMonthPrevious = DATEADD (MONTH, DATEDIFF(MONTH, 0, getdate()) - 1, 0);
SET @dEndMonthPrevious = DATEADD (dd,-DAY(GETDATE()), GETDATE());
SET @dStartWycofania = CONVERT (DATE, GETDATE ()-7, 104);

Jak sprawdziłem dane pobiera poprawnie.
Założyłem deklarację zmiennej jako: DATA a nie DATATIME.

Jak mogę to poproszę o Wasze uwag i łagodny wymiar kary :-)

0

Nie wiem po co tyle tych zmiennych bo nijak się mają do tematu wątku, jedyna uwaga to nie ma sensu zaciemniać zapisu konwersją do DATE bo ta i tak nastąpi podczas przypisania wartości do zmiennej...

0

To czegoś raczej nie rozumiem...

Od czego zależy w jakim formacie zwracana jest "DATA"?
Poniżej wrzuciłem formaty jakie zwracają poszczególne zmienne.
"2017-10-19"
"2017-10-18"
"16.10.2017"
"21.10.2017 2034"
"09.10.2017"
"15.10.2017"
"01.10.2017 2034"
"01.09.2017"
"30.09.2017 2034"
"2017-10-12"

Jutro sprawdzę jak wygląda data w tabeli na serwerze.
Ale z tego co pamiętam, pierwsze dwie zmienne musiałem przekonwertować na układ: 2017-10-19 bo inaczej nie zwracało rekordów z bazy.
Czy jeżeli pole w bazie będzie dd-MM-yyyy to przyjmnie zmienną yyyy-MM-dd?
Do tego jeszcze mamy ggss i stale mam problem z prawidłowym wyborem formaty daty w zapytaniu.
W 99,99% zakresu danych potrzebuję dane dla minimum dla zakresu "dni" z pominięciem godzin...

Zaproponowane rozwiązanie działa SUPER.
Ale przy okazji chciałbym zrozumieć jak formatować DATY w systemie. Zmienne powyższe "załatwiły" kolejny raport, dla tego jest ich więcej.
Ale działa na zaproponowanej zasadzie, którą można w 100% uznać za rozwiązanie problemu.

0

Twój skrypt:

SET DATEFIRST 1 -- Pierwszy dzień tygodnia - PONIEDZIAŁEK.

DECLARE @Today Date; -- Dzisiaj
DECLARE @Yesterday Date; -- Wczoraj
DECLARE @dStartWeek Date; -- Początek obecnego tygodnia
DECLARE @dEndWeek Date; -- Koniec obecnego tygodnia
DECLARE @dStartWeekPrevious Date; -- Początek poprzedniego tygodnia
DECLARE @dEndWeekPrevious Date; -- Koniec poprzedniego tygodnia
DECLARE @dStartMonth Date; -- Początek obecnego miesiąca
DECLARE @dStartMonthPrevious Date; -- Początek poprzedniego miesiąca
DECLARE @dEndMonthPrevious Date; -- Koniec poprzedniego miesiąca
DECLARE @dStartWycofania Date; -- Data przekazań towaru

SET @Today = GETDATE()
SET @Yesterday = GETDATE ()-1;
SET @dStartWeek = DATEADD(wk, DATEDIFF(dd, 0, GETDATE()) / 7, 0);
SET @dEndWeek = GETDATE() + (7 - DATEPART(dw, GETDATE()));
SET @dStartWeekPrevious = DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()) - 1, 0);
SET @dEndWeekPrevious = DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()) -0, 0) - 1;
SET @dStartMonth = DATEADD (dd,-DAY(GETDATE()-1 ), GETDATE());
SET @dStartMonthPrevious = DATEADD (MONTH, DATEDIFF(MONTH, 0, getdate()) - 1, 0);
SET @dEndMonthPrevious = DATEADD (dd,-DAY(GETDATE()), GETDATE());
SET @dStartWycofania = GETDATE ()-7;

print @Today -- GETDATE()
print @Yesterday -- GETDATE ()-1;
print @dStartWeek -- DATEADD(wk, DATEDIFF(dd, 0, GETDATE()) / 7, 0);
print @dEndWeek -- GETDATE() + (7 - DATEPART(dw, GETDATE()));
print @dStartWeekPrevious -- DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()) - 1, 0);
print @dEndWeekPrevious -- DATEADD(WEEK, DATEDIFF(WEEK, 0, getdate()) -0, 0) - 1;
print @dStartMonth -- DATEADD (dd,-DAY(GETDATE()-1 ), GETDATE());
print @dStartMonthPrevious -- DATEADD (MONTH, DATEDIFF(MONTH, 0, getdate()) - 1, 0);
print @dEndMonthPrevious -- DATEADD (dd,-DAY(GETDATE()), GETDATE());
print @dStartWycofania -- GETDATE ()-7;

Zwraca:

2017-10-19
2017-10-18
2017-10-16
2017-10-22
2017-10-09
2017-10-15
2017-10-01
2017-09-01
2017-09-30
2017-10-12

SQL nie trzyma daty w jakimś formacie tylko jako bajty, o formacie zwracanym decyduje użykownik

1 użytkowników online, w tym zalogowanych: 0, gości: 1