[MSSQL] Wybranie wszystkich dni w miesiącu bez procedury

[MSSQL] Wybranie wszystkich dni w miesiącu bez procedury
JU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5046
0

Cześć, próbuję stworzyć selecta, który zwróci mi wszystkie dni w danym miesiącu razem z datami, tzn np dla stycznia:

2009-01-01
2009-01-02
2009-01-03
...
2009-01-31

Chodzi mi o to, żeby zrobić to jednym selectem bez używania procedur lub funkcji składowanych. Da się?

AP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3079
0

W mojej firmie mamy tabelę ze wszystkimi datami do końca świata (tak naprawdę tylko do 2090) i dzięki temu select z tej tabeli jest łatwy, prosty, przyjemny i co najważniejsze nie wiąże się z używaniem jakichkolwiek skomplikowanych zapytań oraz nie obciąża bazy.

Struktura tabeli to coś w tym stylu:

  • rok
  • miesiąc
  • dzień
  • pełna data
  • dzień tygodnia
  • numer tygodnia

IMHO tak właśnie to powinieneś to zrobić. Taka tabela nie zajmuje dużo miejsca, a ile zaoszczędza czasu i zasobów serwera...

/edit: http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html

__Marcin__
  • Rejestracja: dni
  • Ostatnio: dni
0
Kopiuj
select Cast('2009-01-' + Cast(n as varchar) as datetime) date
from
(Select(a*10+b)+1 n 
 from
   (select 0 a union select 1 union select 2 union select 3) a,
   (select 0 b union select 1 union select 2 union select 3 union select 4 union select 5
      union select 6 union select 7 union select 8 union select 9) b
) t
where n <= Day(DateAdd(dd, -1, '2009-02-01'))

W pierwszej linii podajesz rok i miesiąc, które Cię interesują, a w warunku where podajesz pierwszy dzień następnego miesiąca.

SZ
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3356
0

Maly OT, ale gdyby ktos szukal dla Oracle to mozna to zrobic tak:

Kopiuj
SELECT
      g."date", NVL("value", 0)
FROM
-- (g) generator dat
      (SELECT
            CAST(:startdate AS DATE) + num - 1 "date"
      FROM
            (SELECT rownum num
            FROM dual
            CONNECT BY (rownum < CAST(:end AS DATE) - CAST(:startdate AS DATE) + 2)
            )
      ) g
--
LEFT OUTER JOIN
-- (s) dane wejsciowe
      (SELECT "date", "value" FROM
            (SELECT TO_DATE('2003-01-01', 'YYYY-MM-DD') "date", 10 "value" FROM dual UNION
            SELECT TO_DATE('2003-01-03', 'YYYY-MM-DD') "date", 5 "value" FROM dual)
      ) s ON (s."date" = g."date")
--
ORDER BY
      g."date"

Przykladowe dane wejsciowe:

Kopiuj
Date                              Values
2003-01-01                          10
2003-01-03                          5

Przykladowy wynik dla zakresu dat (2003-01-01 – 2003-01-05):

Kopiuj
Date                              Values
2003-01-01                          10
2003-01-02                          0
2003-01-03                          5
2003-01-04                          0
2003-01-05                          0
JU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5046
0

A ja jednak postanowiłem posłużyć się sposobem Adama. Dużo więcej informacji można odczytać, a i join z taką tabelą na pewno będzie szybszy.
Mały minus jest, że żeby taką tabelę utworzyć, ja musiałem na to poświęcić około 2,5 godziny. Dwie godziny wykonywała się procedura wypełniająca daty(od 1900 do 2099 włącznie), a reszta czasu to wklepywanie świąt stałych i implementacja algorytmu na święta ruchome ;)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.