отображать текущий месяц как календарь, используя sql - PullRequest
0 голосов
/ 01 марта 2011

Как написать t-sql для отображения текущего месяца в формате календаря?

вывод должен быть таким, как

sun  mon  tues  wed  thur  fri  sat
           1      2     3     4    5
6    7     8      9     10    11   12
13   14    15     ................

должен дать календарь текущего месяца

Это то, что я до сих пор

declare @start int
declare @day int
declare @space varchar(100)
declare @nodays int
select @start=1
select @space=''
select @nodays=datediff(dd,getdate(),dateadd(mm,1,getdate()))
select @day=case datename(dw,cast(year(getdate()) as varchar(10)) + '-' +cast(month(getdate()) as varchar(10)) + '-' +cast(day(getdate()) as varchar(10))) when 'Sunday' then 1 when 'Monday' then 2 when 'tuesday' then 3 when 'wednesday' then 4 when 'thursday' then 5 when 'friday' then 6 when 'saturday' then 7 end
while(@start<=@nodays)
    if(@day=1)
        if(len(@space)=0)
            select @space=cast(@start as varchar(10))
        else
            select @space=@space+' '+
            case when len(cast(@start as varchar(10)))=1 
            then ' ' 
            else '' 
            end +
            cast(@start as varchar(10))
    else
        if(len(@space)=0)
            select @space=@space+ 
            replicate(char(10),@start) +
            case when len(cast(@start as varchar(10)))=1 
            then ' ' 
            else '' 
            end +
            cast(@start as varchar(10))
        else
            select @space=@space+char(10) + case when len(cast(@start as varchar(10)))=1 then ' ' else '' end +cast(@start as varchar(10))
    select @start=@start+1
print @space+char(10)

Ответы [ 6 ]

3 голосов
/ 01 марта 2011

Вы можете изменить getdate () на локальную объявленную переменную, если хотите.

;with monthDates
as
(
    select  DATEADD(month, datediff(month, 0, getdate()),0) as d
            ,DATEPART(week, DATEADD(month, datediff(month, 0, getdate()),0)) as w
    union all
    select  DATEADD(day, 1, d)
            ,DATEPART(week, DATEADD(day, 1, d))
    from monthDates
    where d < DATEADD(month, datediff(month, 0, getdate())+1,-1)
)

select  max(case when datepart(dw, d) = 1 then datepart(d,d) else null end) as [Sun]
        ,max(case when datepart(dw, d) = 2 then datepart(d,d) else null end) as [Mon]
        ,max(case when datepart(dw, d) = 3 then datepart(d,d) else null end) as [Tue]
        ,max(case when datepart(dw, d) = 4 then datepart(d,d) else null end) as [Wed]
        ,max(case when datepart(dw, d) = 5 then datepart(d,d) else null end) as [Thu]
        ,max(case when datepart(dw, d) = 6 then datepart(d,d) else null end) as [Fri]
        ,max(case when datepart(dw, d) = 7 then datepart(d,d) else null end) as [Sat]
from monthDates
group by w
1 голос
/ 01 марта 2011

select DATEPART(MONTH,getdate()) - получает номер месяца

select Datename(month,getdate()) - получает название месяца

1 голос
/ 01 марта 2011

Забудьте свой «процедурный код для создания календаря на лету»: SQL - декларативный язык, поэтому вместо этого думайте в терминах решений на основе множеств.

Создайте постоянную таблицу Calendar, содержащую все прошлые и будущие даты, которые вам, вероятно, когда-либо понадобятся (должно составлять всего лишь десятки тысяч строк), а затем запросите эту таблицу при необходимости, используя CURRENT_TIMESTAMP.

См. Почему я должен рассмотреть возможность использования вспомогательной календарной таблицы?

1 голос
/ 01 марта 2011

Я не знаю, что вы на самом деле пытаетесь сделать здесь.Печать календарного месяца с помощью T-SQL, вероятно, не то, что вы хотите делать.

Вот запрос, который выдает все даты в текущем месяце в виде набора результатов.Если вы просто хотите получить номер дня месяца (как вы это сделали), вы можете использовать datepart(d, [Date]), чтобы получить его.

;with cteLim as
(
  select
    dateadd(m, datediff(m, 0, getdate()), 0) as FirstDay,
    dateadd(m, datediff(m, 0, getdate())+1, 0)-1 as LastDay
),
cteDays as
(
  select FirstDay as [Date]
  from cteLim
  union all
  select cteDays.[Date] + 1 as [Date]
  from cteDays
    inner join cteLim
      on cteDays.[Date] < cteLim.LastDay
)    
select [Date]
from cteDays

Та же функция, но результат деления на "calender"

;with cteLim as
(
  select
    dateadd(m, datediff(m, 0, getdate()), 0) as FirstDay,
    dateadd(m, datediff(m, 0, getdate())+1, 0)-1 as LastDay
),
cteDays as
(
  select FirstDay as [Date]
  from cteLim
  union all
  select cteDays.[Date] + 1 as [Date]
  from cteDays
    inner join cteLim
      on cteDays.[Date] < cteLim.LastDay
)    
select
  datepart(iso_week, [Date]) as [Week],
  (select datepart(d, D2.[Date])
   from cteDays as D2
   where
    datepart(iso_week, D2.[Date]) = datepart(iso_week, D1.[Date]) and
    datepart(dw, D2.[Date]) = 2) as Mon,
  (select datepart(d, D2.[Date])
   from cteDays as D2
   where
    datepart(iso_week, D2.[Date]) = datepart(iso_week, D1.[Date]) and
    datepart(dw, D2.[Date]) = 3) as Tue,
  (select datepart(d, D2.[Date])
   from cteDays as D2
   where
    datepart(iso_week, D2.[Date]) = datepart(iso_week, D1.[Date]) and
    datepart(dw, D2.[Date]) = 4) as Wed,
  (select datepart(d, D2.[Date])
   from cteDays as D2
   where
    datepart(iso_week, D2.[Date]) = datepart(iso_week, D1.[Date]) and
    datepart(dw, D2.[Date]) = 5) as Thu,
  (select datepart(d, D2.[Date])
   from cteDays as D2
   where
    datepart(iso_week, D2.[Date]) = datepart(iso_week, D1.[Date]) and
    datepart(dw, D2.[Date]) = 6) as Fri,
  (select datepart(d, D2.[Date])
   from cteDays as D2
   where
    datepart(iso_week, D2.[Date]) = datepart(iso_week, D1.[Date]) and
    datepart(dw, D2.[Date]) = 7) as Sat,
  (select datepart(d, D2.[Date])
   from cteDays as D2
   where
    datepart(iso_week, D2.[Date]) = datepart(iso_week, D1.[Date]) and
    datepart(dw, D2.[Date]) = 1) as Sun
from cteDays as D1
group by datepart(iso_week, [Date])

Результат

Week        Mon         Tue         Wed         Thu         Fri         Sat         Sun
----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
9           NULL        1           2           3           4           5           6
10          7           8           9           10          11          12          13
11          14          15          16          17          18          19          20
12          21          22          23          24          25          26          27
13          28          29          30          31          NULL        NULL        NULL
0 голосов
/ 01 марта 2011
DECLARE @Year int, @Month int, @LastDay int;
SET @Year = 2011;
SET @Month = 2;
SET @LastDay = DAY(DATEADD(m, 1, CAST(@Year AS varchar) + '-' +
                                 CAST(@Month AS varchar) + '-01') - 1);

WITH dates AS (
  SELECT *, DOW = DATEPART(WEEKDAY, Date), WN = DATEPART(WEEK, Date)
  FROM (
    SELECT
      Date = CAST(CAST(@Year AS varchar) + '-' +
                  CAST(@Month AS varchar) + '-' +
                  CAST(number AS varchar) AS datetime)
    FROM master..spt_values
    WHERE type = 'P'
      AND number BETWEEN 1 AND @LastDay
  ) s
)
SELECT
  Sun = MAX(CASE days.DOW WHEN 1 THEN dates.Date END),
  Mon = MAX(CASE days.DOW WHEN 2 THEN dates.Date END),
  Tue = MAX(CASE days.DOW WHEN 3 THEN dates.Date END),
  Wed = MAX(CASE days.DOW WHEN 4 THEN dates.Date END),
  Thu = MAX(CASE days.DOW WHEN 5 THEN dates.Date END),
  Fri = MAX(CASE days.DOW WHEN 6 THEN dates.Date END),
  Sat = MAX(CASE days.DOW WHEN 7 THEN dates.Date END)
FROM (SELECT DISTINCT DOW FROM dates) days
  CROSS JOIN (SELECT DISTINCT WN FROM dates) weeks
  LEFT JOIN dates ON weeks.WN = dates.WN AND days.DOW = dates.DOW
GROUP BY weeks.WN
0 голосов
/ 01 марта 2011

здесь ссылка для: Создание календаря в одном операторе SQL

SELECT LPAD(MONTH, 20 - (20 - LENGTH(MONTH)) / 2) MONTH, "Sun", "Mon", "Tue", "Wed",     "Thu", "Fri", "Sat"
  FROM (SELECT TO_CHAR(dt, 'fmMonthfm YYYY') MONTH,
               TO_CHAR(dt + 1, 'iw') week,
               MAX(DECODE(TO_CHAR(dt, 'd'), '1', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Sun",
               MAX(DECODE(TO_CHAR(dt, 'd'), '2', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Mon",
               MAX(DECODE(TO_CHAR(dt, 'd'), '3', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Tue",
               MAX(DECODE(TO_CHAR(dt, 'd'), '4', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Wed",
               MAX(DECODE(TO_CHAR(dt, 'd'), '5', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Thu",
               MAX(DECODE(TO_CHAR(dt, 'd'), '6', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Fri",
               MAX(DECODE(TO_CHAR(dt, 'd'), '7', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Sat"
          FROM (SELECT TRUNC(SYSDATE, 'y') - 1 + ROWNUM dt
                  FROM all_objects
                  WHERE ROWNUM <= ADD_MONTHS(TRUNC(SYSDATE, 'y'), 12) -
                       TRUNC(SYSDATE, 'y'))
         GROUP BY TO_CHAR(dt, 'fmMonthfm YYYY'), TO_CHAR(dt + 1, 'iw'))
 ORDER BY TO_DATE(MONTH, 'Month YYYY'), TO_NUMBER(week);

Вы можете добавить несколько пунктов, чтобы указать месяц

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...