Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 календарь нынешнего месяца  [new]
Erik_Kartmann
Member

Откуда: Пиндырдышханда
Сообщений: 948
вот составил, но очень длинный зпрос получаетса. вывел только понедельник, что и так нездорово.
нужно в виде год-месяц-день
Select woch.woche, pn.datestr as ponedelnik
From(
Select DISTINCT datepart(ww, cast(datestr  as datetime)) as woche 
From(
Select num, 
DATENAME ( yy , getdate() )+'-'+
CASE LEN(Month( getdate() )) WHEN 1 Then
('0'+CAST(Month( getdate() ) As Varchar)) 
else (CAST(Month( getdate() ) As Varchar)) 
end +'-' + case when num<10 
then '0' + cast(num as VARCHAR) 
else cast(num as VARCHAR) end as datestr
From(
SELECT 10*(a-1)+b as num FROM
   (SELECT 1 a UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 
      UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 
      UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) x 
CROSS JOIN
   (SELECT 1 b UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 
      UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7
      UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) y 
)z1 where num < datediff(dd, getdate(), dateadd(mm, 1, getdate()))
)d
)woch
Left join
(
Select DISTINCT datepart(ww, cast(datestr  as datetime)) as woche, datestr
From(
Select num, 
DATENAME ( yy , getdate() )+'-'+
CASE LEN(Month( getdate() )) WHEN 1 Then
('0'+CAST(Month( getdate() ) As Varchar)) 
else (CAST(Month( getdate() ) As Varchar)) 
end +'-' + case when num<10 
then '0' + cast(num as VARCHAR) 
else cast(num as VARCHAR) end as datestr
From(
SELECT 10*(a-1)+b as num FROM
   (SELECT 1 a UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 
      UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 
      UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) x 
CROSS JOIN
   (SELECT 1 b UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 
      UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7
      UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) y 
)z1 where num < datediff(dd, getdate(), dateadd(mm, 1, getdate()))
)d where datepart(dw, cast(datestr  as datetime))=2
) pn
on pn.woche = woch.woche
28 янв 08, 17:34    [5212516]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
radya
Member

Откуда: Москва
Сообщений: 20
Привет
Посмотри в BOL описание функции CONVERT. Это то-что тебе нужно
28 янв 08, 17:39    [5212549]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 33930
Блог
Msg 8115, Level 16, State 2, Line 1
Arithmetic overflow error converting expression to data type datetime.

на

Microsoft SQL Server 2000 - 8.00.760 (Intel X86) Dec 17 2002 14:22:05 Copyright (c) 1988-2003 Microsoft Corporation Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2)

Microsoft SQL Server 2005 - 9.00.3054.00 (X64) Mar 23 2007 18:41:50 Copyright (c) 1988-2005 Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 5.2 (Build 3790: Service Pack 2)

Вообще, создайте что-ли табличку с календарем
28 янв 08, 17:52    [5212642]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
Erik_Kartmann
Member

Откуда: Пиндырдышханда
Сообщений: 948
>Arithmetic overflow error converting expression to data type datetime.
У вас SQL Server 2000 ? Я угадал? )))
В таком формате ошибки не будет : '01/13/2008'
28 янв 08, 17:57    [5212689]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
Erik_Kartmann
Member

Откуда: Пиндырдышханда
Сообщений: 948
всмысле на 2000м это работает, а на 2005 - уже нет.
28 янв 08, 18:00    [5212711]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
Glory
Member

Откуда:
Сообщений: 104760
Erik_Kartmann
всмысле на 2000м это работает, а на 2005 - уже нет.

А разве без left outer join нельзя обойтись ?
28 янв 08, 18:09    [5212763]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
Erik_Kartmann
Member

Откуда: Пиндырдышханда
Сообщений: 948
radya
Привет
Посмотри в BOL описание функции CONVERT. Это то-что тебе нужно

хмм.. а что там ?
Вобщем есть ли алгоритм, чтоб сам запрос уменьшить, и количество писанины?
28 янв 08, 18:31    [5212888]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
aleks2
Guest
Erik_Kartmann
radya
Привет
Посмотри в BOL описание функции CONVERT. Это то-что тебе нужно

хмм.. а что там ?
Вобщем есть ли алгоритм, чтоб сам запрос уменьшить, и количество писанины?


Нарисуй пример того, что надо получить в РЕЗУЛЬТАТЕ, а то разбираться в этом потоке воспаленного сознания неохота...
28 янв 08, 18:58    [5212995]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
Erik_Kartmann
Member

Откуда: Пиндырдышханда
Сообщений: 948
Guest, клацни на часы в правом нижнем углу..
так.. появитса окно "Свойства: дата и время".
А слева календарик текущщего месяца. Его подобие я и хочю создать запросом.
28 янв 08, 19:06    [5213012]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
Taffy
Member

Откуда:
Сообщений: 20501
Гы, у нас на фирме это тестовое задание при приеме на работу
Рассматриваю чужие коды решила посмотреть - на что сама способна
Мой код
SET DATEFIRST 2

declare @rdate datetime
select @rdate = '20060327'

declare @fd int , @bdate datetime

select  @bdate = dateadd(day,1-datepart(day,@rdate),@rdate)
select @fd = datepart(dw,@bdate)

--Вспомогательная таблица натуральных чисел - должна быть в каждой базе
declare @s table (d int)
insert into @s select 1
insert into @s select 2
insert into @s select 3
insert into @s select 4
insert into @s select 5
insert into @s select 6
insert into @s select 7
insert into @s select 8
insert into @s select 9
insert into @s select 10
insert into @s select 11
insert into @s select 12
insert into @s select 13
insert into @s select 14
insert into @s select 15
insert into @s select 16
insert into @s select 17
insert into @s select 18
insert into @s select 19
insert into @s select 20
insert into @s select 21
insert into @s select 22
insert into @s select 23
insert into @s select 24
insert into @s select 25
insert into @s select 26
insert into @s select 27
insert into @s select 28
insert into @s select 29
insert into @s select 30
insert into @s select 31





select t.d ,
	s1 = MAX(case when datepart(dw,dateadd(dd,s.d,@bdate)) = 1 then s.d else NULL end),
	s2 = MAX(case when datepart(dw,dateadd(dd,s.d,@bdate)) = 2 then s.d else NULL end),
	s3 = MAX(case when datepart(dw,dateadd(dd,s.d,@bdate)) = 3 then s.d else NULL end),
	s4 = MAX(case when datepart(dw,dateadd(dd,s.d,@bdate)) = 4 then s.d else NULL end),
	s5 = MAX(case when datepart(dw,dateadd(dd,s.d,@bdate)) = 5 then s.d else NULL end),
	s6 = MAX(case when datepart(dw,dateadd(dd,s.d,@bdate)) = 6 then s.d else NULL end),
	s7 = MAX(case when datepart(dw,dateadd(dd,s.d,@bdate)) = 7 then s.d else NULL end)
from @s s inner join 
	@s t on t.d= ceiling((s.d+@fd)/7.0)
where s.d <= datediff(day,@bdate, dateadd(day,-1,dateadd(month,1,@bdate)))+1
group by t.d
28 янв 08, 19:14    [5213037]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
Erik_Kartmann
Member

Откуда: Пиндырдышханда
Сообщений: 948
Taffy, красиво, и короче, чем мой вариант. Наверное он даже бы сюда не влез.
зачёд! ;)
28 янв 08, 19:22    [5213053]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
Smirnov Anton
Member

Откуда: Н.Новгород
Сообщений: 3220
для 2005 (хотя всё cte лишь от неимения таблички натуральных чисел)
set datefirst 1
go
with ln(num) as (select 0 as num union all select 1  union all select 2 union all select 3  union all select 4),
bn(date) as (select cast('20071231' as smalldatetime)-(t1.num+5*t2.num+25*t3.num+125*t4.num) from ln t1,ln t2,ln t3,ln t4),
dates(date) as (select date from bn where date between '20070101' and '20071231')
select m,[пон], [вт ], [ср ], [чтв], [птн], [сб ], [вс ]
 from (
select
 date,2 as ord, 
 ' ' as m,
 case when m=month(dateadd(day,0-seek,date))  then cast(day(dateadd(day,0-seek,date)) as varchar(2)) else '' end as 'пон',
 case when m=month(dateadd(day,1-seek,date))  then cast(day(dateadd(day,1-seek,date)) as varchar(2)) else '' end as 'вт ',
 case when m=month(dateadd(day,2-seek,date))  then cast(day(dateadd(day,2-seek,date)) as varchar(2)) else '' end as 'ср ',
 case when m=month(dateadd(day,3-seek,date))  then cast(day(dateadd(day,3-seek,date)) as varchar(2)) else '' end as 'чтв',
 case when m=month(dateadd(day,4-seek,date))  then cast(day(dateadd(day,4-seek,date)) as varchar(2)) else '' end as 'птн',
 case when m=month(dateadd(day,5-seek,date))  then cast(day(dateadd(day,5-seek,date)) as varchar(2)) else '' end as 'сб ',
 case when m=month(dateadd(day,6-seek,date))  then cast(day(dateadd(day,6-seek,date)) as varchar(2)) else '' end as 'вс '
 from(
select date,datepart(month,date) as m,datepart(weekday,date)-1 as seek from dates where day(date)=1 or datepart(weekday,date)=1) t
union all
select  date,1 as ord,case month(date)
        when 1 then N'январь'
        when 2 then N'февраль'
        when 3 then N'март'
        when 4 then N'апрель'
        when 5 then N'май'
        when 6 then N'июнь'
        when 7 then N'июль'
        when 8 then N'август'
        when 9 then N'сентябрь'
        when 10 then N'октябрь'
        when 11 then N'ноябрь'
        when 12 then N'декабрь'
  end + ' '+cast(year(date) as varchar(4))+N'года' ,
 '---' as N'пон',
 '---' as N'вт ',
 '---' as N'ср ',
 '---' as N'чтв',
 '---' as N'птн',
 '---' as N'сб ',
 '---' as N'вс '
 from dates where day(date)=1 )tt
order by date,ord
если 2000 - то можно потестить вот это
28 янв 08, 19:41    [5213101]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
Для одного месяца
DECLARE @D DATETIME;
SET @D=GETDATE();
SELECT
 MAX(ISNULL(CASE(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(DAY,V.number,M.D)))%7 WHEN 2 THEN STR(V.number+1)END,''))[Пн],
 MAX(ISNULL(CASE(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(DAY,V.number,M.D)))%7 WHEN 3 THEN STR(V.number+1)END,''))[Вт],
 MAX(ISNULL(CASE(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(DAY,V.number,M.D)))%7 WHEN 4 THEN STR(V.number+1)END,''))[Ср],
 MAX(ISNULL(CASE(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(DAY,V.number,M.D)))%7 WHEN 5 THEN STR(V.number+1)END,''))[Чт],
 MAX(ISNULL(CASE(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(DAY,V.number,M.D)))%7 WHEN 6 THEN STR(V.number+1)END,''))[Пт],
 MAX(ISNULL(CASE(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(DAY,V.number,M.D)))%7 WHEN 0 THEN STR(V.number+1)END,''))[Сб],
 MAX(ISNULL(CASE(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(DAY,V.number,M.D)))%7 WHEN 1 THEN STR(V.number+1)END,''))[Вс]
FROM (SELECT CONVERT(CHAR(6),@D,112)+'01') M(D)
JOIN master.dbo.spt_values V ON type='P' AND V.number<DATEDIFF(DAY,M.D, DATEADD(MONTH,1,M.D))
GROUP BY (V.number+(@@DATEFIRST+DATEPART(WEEKDAY,M.D)-2)%7)/7;
28 янв 08, 22:40    [5213452]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
Календарь на заданный месяц:
DECLARE @M CHAR(6);
SET @M='200805';

SELECT LEFT(CASE(D-1+(@@DATEFIRST+DATEPART(WEEKDAY,@M+'01')-2)%7)/7 WHEN 0 THEN DATENAME(MONTH, @M+'01') ELSE '' END,8) [Месяц],
 MAX(ISNULL(CASE WD WHEN 2 THEN STR(D)END,''))[Пн],
 MAX(ISNULL(CASE WD WHEN 3 THEN STR(D)END,''))[Вт],
 MAX(ISNULL(CASE WD WHEN 4 THEN STR(D)END,''))[Ср],
 MAX(ISNULL(CASE WD WHEN 5 THEN STR(D)END,''))[Чт],
 MAX(ISNULL(CASE WD WHEN 6 THEN STR(D)END,''))[Пт],
 MAX(ISNULL(CASE WD WHEN 0 THEN STR(D)END,''))[Сб],
 MAX(ISNULL(CASE WD WHEN 1 THEN STR(D)END,''))[Вс]
FROM
(
 SELECT number+1,(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(DAY,number,@M+'01')))%7
 FROM master.dbo.spt_values
 WHERE [type]='P' AND number<DATEDIFF(DAY,@M+'01', DATEADD(MONTH,1,@M+'01'))
) T(D,WD)
GROUP BY (D-1+(@@DATEFIRST+DATEPART(WEEKDAY,@M+'01')-2)%7)/7
ORDER BY (D-1+(@@DATEFIRST+DATEPART(WEEKDAY,@M+'01')-2)%7)/7;
Календарь на весь год:
DECLARE @Y CHAR(4);
SET @Y='2008';
PRINT 'КАЛЕНДАРЬ НА '+@Y+' ГОД';
PRINT '---------------------';
SELECT LEFT(CASE(D-1+(@@DATEFIRST+DATEPART(WEEKDAY,DATEADD(MONTH,M-1,@Y))-2)%7)/7 WHEN 0 THEN MN ELSE''END,8),
 MAX(ISNULL(CASE WD WHEN 2 THEN STR(D)END,''))[Пн],
 MAX(ISNULL(CASE WD WHEN 3 THEN STR(D)END,''))[Вт],
 MAX(ISNULL(CASE WD WHEN 4 THEN STR(D)END,''))[Ср],
 MAX(ISNULL(CASE WD WHEN 5 THEN STR(D)END,''))[Чт],
 MAX(ISNULL(CASE WD WHEN 6 THEN STR(D)END,''))[Пт],
 MAX(ISNULL(CASE WD WHEN 0 THEN STR(D)END,''))[Сб],
 MAX(ISNULL(CASE WD WHEN 1 THEN STR(D)END,''))[Вс]
FROM
(
 SELECT
  M.number+1,
  DATENAME(MONTH, DATEADD(MONTH,M.number,@Y)),
  MD.number+1,
  (@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(DAY,MD.number, DATEADD(MONTH,M.number,@Y))))%7
 FROM master.dbo.spt_values M
 JOIN master.dbo.spt_values MD
 ON MD.number<DATEDIFF(DAY, DATEADD(MONTH,M.number,@Y), DATEADD(MONTH,M.number+1,@Y))
 WHERE M.[type]='P' AND M.number<12 AND MD.[type]='P'
) T(M,MN,D,WD)
GROUP BY M,MN,(D-1+(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(MONTH,M-1,@Y))-2)%7)/7
ORDER BY M,(D-1+(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(MONTH,M-1,@Y))-2)%7)/7;
29 янв 08, 10:25    [5214457]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
dante77
Member

Откуда: Москва
Сообщений: 371
в догонку календарь на этот год :))
SET DATEFIRST 1
DECLARE @data datetime
DECLARE @tab table (days int, weekdays int)
DECLARE @datafirst datetime
DECLARE @datalast datetime
DECLARE @nom int
SET @data = '07/05/2008'
SET @datafirst = DATEADD(day, 1 - DAY(@data), @data)
SET @datalast = DATEADD(month, 1, DATEADD(day, 1 - DAY(@data), @data))-1
WHILE @datafirst <= @datalast
	BEGIN
		INSERT INTO @tab
		SELECT DATEPART(day, @datafirst), DATEPART(weekday, @datafirst);
		SET @datafirst = DATEADD(day, 1, @datafirst)
	END
SET @datafirst = DATEADD(day, 1 - DAY(@data), @data)
SELECT @nom = 10 - MIN(CASE weekdays WHEN 7 THEN days END) FROM @tab;
SELECT
	MAX(CASE weekdays WHEN 1 THEN days END) П,
	MAX(CASE weekdays WHEN 2 THEN days END) В,
	MAX(CASE weekdays WHEN 3 THEN days END) С,
	MAX(CASE weekdays WHEN 4 THEN days END) Ч,
	MAX(CASE weekdays WHEN 5 THEN days END) П,
	MAX(CASE weekdays WHEN 6 THEN days END) С,
	MAX(CASE weekdays WHEN 7 THEN days END) В
FROM @tab s
GROUP BY 
	CASE
		WHEN (days + @nom) <= 10 then 1
		WHEN (days + @nom + 3) between 10 and 20  THEN 2 
		WHEN (days + @nom + 6) between 20 and 30  THEN 3 
		WHEN (days + @nom + 9) between 30 and 40  THEN 4 
		WHEN (days + @nom + 12) between 40 and 50  THEN 5 
		WHEN (days + @nom + 15) between 50 and 60  THEN 6 END;
4 фев 08, 18:43    [5242720]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
Тогда в догонку ещё два варианта (для SQL2005):
1. Календарь на 2008 год с использованием CTE вместо подзапросов:
SET NOCOUNT ON;
DECLARE @Language NVARCHAR(4000);
SET @Language=@@LANGUAGE;
IF @@LANGUAGE<>N'русский' SET LANGUAGE Russian;
DECLARE @Y CHAR(4);
SET @Y='2008';
PRINT 'КАЛЕНДАРЬ НА '+@Y+' ГОД';
PRINT '---------------------';
WITH T(M,MN,D,WD) AS
(
 SELECT M.number+1, DATENAME(MONTH, DATEADD(MONTH,M.number,@Y)),MD.number+1,(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(DAY,MD.number, DATEADD(MONTH,M.number,@Y))))%7
 FROM master.dbo.spt_values M JOIN master.dbo.spt_values MD ON MD.number<DATEDIFF(DAY, DATEADD(MONTH,M.number,@Y), DATEADD(MONTH,M.number+1,@Y))
 WHERE M.[type]='P' AND M.number<12 AND MD.[type]='P'
)
SELECT LEFT(CASE(D-1+(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(MONTH,M-1,@Y))-2)%7)/7 WHEN 0 THEN MN ELSE''END,8),
 MAX(CASE WD WHEN 2 THEN STR(D)ELSE''END)[Пн],
 MAX(CASE WD WHEN 3 THEN STR(D)ELSE''END)[Вт],
 MAX(CASE WD WHEN 4 THEN STR(D)ELSE''END)[Ср],
 MAX(CASE WD WHEN 5 THEN STR(D)ELSE''END)[Чт],
 MAX(CASE WD WHEN 6 THEN STR(D)ELSE''END)[Пт],
 MAX(CASE WD WHEN 0 THEN STR(D)ELSE''END)[Сб],
 MAX(CASE WD WHEN 1 THEN STR(D)ELSE''END)[Вс]
FROM T
GROUP BY M,MN,(D-1+(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(MONTH,M-1,@Y))-2)%7)/7
ORDER BY M,(D-1+(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(MONTH,M-1,@Y))-2)%7)/7;
IF @@LANGUAGE<>@Language SET LANGUAGE @Language;
2. Календарь на несколько лет. Даты генерируются рекурсивным CTE вместо использования master.dbo.spt_values. MAX(CASE) заменены на PIVOT. Рекурсивные CTE, конечно тормозят, но календарь с 01.01.1754 до 31.12.2009 у нас на сервере получился за 8 секунд
SET NOCOUNT ON;
DECLARE @FromYear CHAR(4),@ToYear CHAR(4),@FromMonth TINYINT,@ToMonth TINYINT;
SELECT @FromYear='2001',@ToYear='2008',@FromMonth=1,@ToMonth=12;
DECLARE @Language NVARCHAR(4000);
SET @Language=@@LANGUAGE;
IF @@LANGUAGE<>N'русский' SET LANGUAGE Russian;
WITH Years(Y) AS (SELECT @FromYear UNION ALL SELECT CAST(Y+1 AS CHAR(4))FROM Years WHERE Y<@ToYear)
,Monthes(Y,M,N) AS (SELECT Y,@FromMonth-1, DATENAME(MONTH, DATEADD(MONTH,@FromMonth-1,Y)) FROM Years UNION ALL SELECT Y,M+1, DATENAME(MONTH, DATEADD(MONTH,M+1,Y)) FROM Monthes WHERE M<@ToMonth-1)
,Dates(Y,M,D,DD,N) AS (SELECT Y,M,0, DATEADD(MONTH,M,Y),N FROM Monthes UNION ALL SELECT Y,M,D+1, DATEADD(DAY,1,DD),N FROM Dates WHERE D<DATEDIFF(DAY, DATEADD(MONTH,M,Y), DATEADD(MONTH,M+1,Y))-1)
,WeekDays(Y,M,D,WD,N,WNo) AS (SELECT Y,M+1, RIGHT(STR(D+1),2),(@@DATEFIRST+DATEPART(WEEKDAY,DD))%7,N,(D+(@@DATEFIRST+DATEPART(WEEKDAY, DATEADD(MONTH,M,Y))-2)%7)/7 FROM Dates)
,Calendar AS
(
 SELECT Y,M,WNo
, CASE WHEN WNo=0 AND M=@FromMonth THEN Y ELSE''END[Год]
, LEFT(CASE WNo WHEN 0 THEN CASE M WHEN 1 THEN REPLICATE('=',8)ELSE REPLICATE('-',8)END WHEN 2 THEN N ELSE''END,8)[Месяц]
, ISNULL([2],'')[Пн]
, ISNULL([3],'')[Вт]
, ISNULL([4],'')[Ср]
, ISNULL([5],'')[Чт]
, ISNULL([6],'')[Пт]
, ISNULL('['+[0]+']','')[Сб]
, ISNULL('['+[1]+']','')[Вс]
 FROM WeekDays PIVOT (MAX(D) FOR WD IN([0],[1],[2],[3],[4],[5],[6])) Pvt
)
SELECT [Год],[Месяц],[Пн],[Вт],[Ср],[Чт],[Пт],[Сб],[Вс] FROM Calendar ORDER BY Y,M,WNo OPTION(MAXRECURSION 0);
IF @@LANGUAGE<>@Language SET LANGUAGE @Language;
В отличие от вариантов с SET DATEFIRST 1, данные запросы можно, например, оформить в виде функций.
4 фев 08, 20:03    [5242946]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
dante77
Member

Откуда: Москва
Сообщений: 371
iap
В отличие от вариантов с SET DATEFIRST 1, данные запросы можно, например, оформить в виде функций.

А интересно, почему вариант с SET DATEFIRST 1 в виде процедуры оформить удается, а в виде функции, возвращающей таблицу - нет?
5 фев 08, 09:43    [5243863]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
dante77
iap
В отличие от вариантов с SET DATEFIRST 1, данные запросы можно, например, оформить в виде функций.

А интересно, почему вариант с SET DATEFIRST 1 в виде процедуры оформить удается, а в виде функции, возвращающей таблицу - нет?
Потому что в функциях SET <COMMAND> применять запрещено! Как и всё, что порождает побочные эффекты (изменение таблиц, вызов процедур, динамический запрос...). Есть одно исключение - extended stored procedures.
5 фев 08, 12:06    [5245117]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
dante77
Member

Откуда: Москва
Сообщений: 371
ааа, ну ясненько, спасибо за разъяснения!
5 фев 08, 13:12    [5245798]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
andrey odegov
Member

Откуда:
Сообщений: 473
select dateadd(d, 7 * n.nbr + 0, t5.wbeg) as mo
, dateadd(d, 7 * n.nbr + 1, t5.wbeg) as tu
, dateadd(d, 7 * n.nbr + 2, t5.wbeg) as we
, dateadd(d, 7 * n.nbr + 3, t5.wbeg) as th
, dateadd(d, 7 * n.nbr + 4, t5.wbeg) as fr
, dateadd(d, 7 * n.nbr + 5, t5.wbeg) as sa
, dateadd(d, 7 * n.nbr + 6, t5.wbeg) as su
from (select 0 union all select 1 union all select 2 union all
select 3 union all select 4 union all select 5) as n(nbr)
, (select wbeg, datediff(wk, wbeg, wend) as wks
from (select mbeg, mend, wbeg
, dateadd(d, datediff(d, 0, mend) / 7 * 7 + 6, 0) as wend
from (select mbeg
, dateadd(m, 1, mbeg) - 1 as mend
, dateadd(d, datediff(d, 0, mbeg) / 7 * 7, 0) as wbeg
from (select dateadd(d, -datepart(d, cdate) + 1, cdate) as mbeg
from (select current_timestamp as cdate) as t1
) as t2
) as t3
) as t4
) as t5
where t5.wks >= n.nbr + 1
5 фев 08, 16:18    [5247343]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
dante77
Member

Откуда: Москва
Сообщений: 371
andrey odegov
select dateadd(d, 7 * n.nbr + 0, t5.wbeg) as mo
, dateadd(d, 7 * n.nbr + 1, t5.wbeg) as tu
, dateadd(d, 7 * n.nbr + 2, t5.wbeg) as we
, dateadd(d, 7 * n.nbr + 3, t5.wbeg) as th
, dateadd(d, 7 * n.nbr + 4, t5.wbeg) as fr
, dateadd(d, 7 * n.nbr + 5, t5.wbeg) as sa
, dateadd(d, 7 * n.nbr + 6, t5.wbeg) as su
from (select 0 union all select 1 union all select 2 union all
select 3 union all select 4 union all select 5) as n(nbr)
, (select wbeg, datediff(wk, wbeg, wend) as wks
from (select mbeg, mend, wbeg
, dateadd(d, datediff(d, 0, mend) / 7 * 7 + 6, 0) as wend
from (select mbeg
, dateadd(m, 1, mbeg) - 1 as mend
, dateadd(d, datediff(d, 0, mbeg) / 7 * 7, 0) as wbeg
from (select dateadd(d, -datepart(d, cdate) + 1, cdate) as mbeg
from (select current_timestamp as cdate) as t1
) as t2
) as t3
) as t4
) as t5
where t5.wks >= n.nbr + 1

Пробовал запускать - что-то не получается календарь как Windows!
2008-01-28 00:00:00.000	2008-01-29 00:00:00.000	2008-01-30 00:00:00.000	2008-01-31 00:00:00.000	2008-02-01 00:00:00.000	2008-02-02 00:00:00.000	2008-02-03 00:00:00.000
2008-02-04 00:00:00.000	2008-02-05 00:00:00.000	2008-02-06 00:00:00.000	2008-02-07 00:00:00.000	2008-02-08 00:00:00.000	2008-02-09 00:00:00.000	2008-02-10 00:00:00.000
2008-02-11 00:00:00.000	2008-02-12 00:00:00.000	2008-02-13 00:00:00.000	2008-02-14 00:00:00.000	2008-02-15 00:00:00.000	2008-02-16 00:00:00.000	2008-02-17 00:00:00.000
2008-02-18 00:00:00.000	2008-02-19 00:00:00.000	2008-02-20 00:00:00.000	2008-02-21 00:00:00.000	2008-02-22 00:00:00.000	2008-02-23 00:00:00.000	2008-02-24 00:00:00.000
2008-02-25 00:00:00.000	2008-02-26 00:00:00.000	2008-02-27 00:00:00.000	2008-02-28 00:00:00.000	2008-02-29 00:00:00.000	2008-03-01 00:00:00.000	2008-03-02 00:00:00.000
5 фев 08, 18:45    [5248458]     Ответить | Цитировать Сообщить модератору
 Re: календарь нынешнего месяца  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
Таaк... Продолжаем?
Снова SQL2005:
SET NOCOUNT ON;
DECLARE @FromMonth CHAR(6),@ToMonth CHAR(6);
SELECT @FromMonth='200101',@ToMonth='200901';
DECLARE @Language NVARCHAR(4000);
SET @Language=@@LANGUAGE;
IF @@LANGUAGE<>N'русский' SET LANGUAGE Russian;
WITH
 Dates(D)AS(SELECT CAST(@FromMonth+'01' AS DATETIME) UNION ALL SELECT DATEADD(DAY,1,D) FROM Dates WHERE D<DATEADD(DAY,-1,@ToMonth+'01'))
,WeekDays(Y,M,D,WD,N,WNo)AS(SELECT YEAR(D), MONTH(D), STR(DAY(D),2),(@@DATEFIRST+DATEPART(WEEKDAY,D))%7, DATENAME(MONTH,D),(DAY(D)-1+(@@DATEFIRST+DATEPART(WEEKDAY, CONVERT(CHAR(6),D,112)+'01')-2)%7)/7 FROM Dates)
,Calendar AS
(
 SELECT Y,M,WNo
, CASE WHEN WNo=0 AND M=1 THEN STR(Y,4) ELSE''END[Год]
, LEFT(CASE WNo WHEN 0 THEN CASE M WHEN 1 THEN REPLICATE('=',8)ELSE REPLICATE('-',8)END WHEN 2 THEN N ELSE''END,8)[Месяц]
, ISNULL([2],'')[Пн]
, ISNULL([3],'')[Вт]
, ISNULL([4],'')[Ср]
, ISNULL([5],'')[Чт]
, ISNULL([6],'')[Пт]
, ISNULL('['+[0]+']','')[Сб]
, ISNULL('['+[1]+']','')[Вс]
 FROM WeekDays PIVOT (MAX(D) FOR WD IN([0],[1],[2],[3],[4],[5],[6])) Pvt
)
SELECT [Год],[Месяц],[Пн],[Вт],[Ср],[Чт],[Пт],[Сб],[Вс] FROM Calendar ORDER BY Y,M,WNo OPTION(MAXRECURSION 0);
IF @@LANGUAGE<>@Language SET LANGUAGE @Language;
Первое CTE (рекурсивное)можно заменить на SELECT из таблицы с датами. OPTION(MAXRECURSION 0) тогда можно выбросить.
5 фев 08, 20:21    [5248672]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить