SQL做日历
DECLARE @DATE DATETIME
SET @DATE=GETDATE() SELECT
SUN=MAX(CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END+CASE WHEN DATEPART(WEEKDAY,DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))=1 THEN LTRIM(DAY(DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))) ELSE '' END+CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END)
,MON=MAX(CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END+CASE WHEN DATEPART(WEEKDAY,DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))=2 THEN LTRIM(DAY(DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))) ELSE '' END+CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END)
,TUE=MAX(CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END+CASE WHEN DATEPART(WEEKDAY,DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))=3 THEN LTRIM(DAY(DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))) ELSE '' END+CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END)
,WED=MAX(CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END+CASE WHEN DATEPART(WEEKDAY,DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))=4 THEN LTRIM(DAY(DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))) ELSE '' END+CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END)
,THU=MAX(CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END+CASE WHEN DATEPART(WEEKDAY,DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))=5 THEN LTRIM(DAY(DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))) ELSE '' END+CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END)
,FRI=MAX(CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END+CASE WHEN DATEPART(WEEKDAY,DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))=6 THEN LTRIM(DAY(DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))) ELSE '' END+CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END)
,SAT=MAX(CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END+CASE WHEN DATEPART(WEEKDAY,DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))=7 THEN LTRIM(DAY(DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))) ELSE '' END+CASE WHEN DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))=@DATE THEN '*' ELSE '' END)
FROM MASTER..SPT_VALUES
WHERE TYPE='P' AND DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE))<DATEADD(MONTH,1,DATEADD(DAY,1-DAY(@DATE),@DATE))
GROUP BY DATEPART(WEEK,DATEADD(DAY,NUMBER,DATEADD(DAY,1-DAY(@DATE),@DATE)))
/*
SUN MON TUE WED THU FRI SAT
-------------- -------------- -------------- -------------- -------------- -------------- --------------
1 2 3 4
5 6 7 8 9 10 11
12 13 14 *15* 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
*/ 根据月份得出日历,求一sql
日 一 二 三 四 五 六
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 像这样的
--------------------------------------- declare @month as varchar(7)
set @month = '2007-12' select 日,一,二,三,四,五,六 from
(
select week ,
max(case weekday when 1 then datename(day,dt) else '' end ) '日',
max(case weekday when 2 then datename(day,dt) else '' end ) '一',
max(case weekday when 3 then datename(day,dt) else '' end ) '二',
max(case weekday when 4 then datename(day,dt) else '' end ) '三',
max(case weekday when 5 then datename(day,dt) else '' end ) '四',
max(case weekday when 6 then datename(day,dt) else '' end ) '五',
max(case weekday when 7 then datename(day,dt) else '' end ) '六'
from
(
select week = datepart(week , m.dt) , weekday = datepart(weekday , m.dt) , dt from
(
select dt = @month + '-' + right(''+cast(t.id as varchar),2) from
(
select 1 as id union select 2 union select 3 union select 4 union select 5
union select 6 union select 7 union select 8 union select 9 union select 10
union select 11 union select 12 union select 13 union select 14 union select 15
union select 16 union select 17 union select 18 union select 19 union select 20
union select 21 union select 22 union select 23 union select 24 union select 25
union select 26 union select 27 union select 28 union select 29 union select 30
union select 31
) t
where isdate(@month + '-' + right(''+cast(t.id as varchar),2)) = 1 and @month + '-' + right(''+cast(t.id as varchar),2) <= dateadd(month , 1 , @month + '-01')
) m
) n
group by week
) o
/*
日 一 二 三 四 五 六
-- -- -- -- -- -- --
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 (所影响的行数为 6 行)
*/ ----------------------------------------------------------------------
用函数解决。(libin_ftsafe)
create function f_calendar(@year int,@month int)
returns @t table(日 varchar(4),一 varchar(4),二 varchar(4),三 varchar(4),四 varchar(4),五 varchar(4),六 varchar(4))
as
begin declare @a table(id int identity(0,1),date datetime) insert into @a(date)
select top 31 rtrim(@year)+'-'+rtrim(@month)+'-1' from sysobjects update @a set date=dateadd(dd,id,date) insert into @t
select
max(case datepart(dw,date) when 7 then rtrim(day(date)) else '' end),
max(case datepart(dw,date) when 1 then rtrim(day(date)) else '' end),
max(case datepart(dw,date) when 2 then rtrim(day(date)) else '' end),
max(case datepart(dw,date) when 3 then rtrim(day(date)) else '' end),
max(case datepart(dw,date) when 4 then rtrim(day(date)) else '' end),
max(case datepart(dw,date) when 5 then rtrim(day(date)) else '' end),
max(case datepart(dw,date) when 6 then rtrim(day(date)) else '' end)
from
@a
where
month(date)=@month
group by
(case datepart(dw,date) when 7 then datepart(week,date)+1 else datepart(week,date) end) return
end
go set datefirst 1
select * from dbo.f_calendar(2007,12)
/*
日 一 二 三 四 五 六
---- ---- ---- ---- ---- ---- ----
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
*/
go drop function f_calendar
go --去年没事写的玩的 --获取每个月日历 CREATE PROC GetEveryDayOfMonth(@date datetime)
AS
BEGIN
SET NOCOUNT ON
SET datefirst 1
DECLARE @DateBegin DateTime,@DateEnd DateTime
DECLARE @Sun varchar(2),@Mon varchar(2),@Tue varchar(2),@Wed varchar(2),
@Thu varchar(2),@Fir varchar(2),@Sta varchar(2) SET @DateBegin=CONVERT(VARCHAR(7),@date,120)+'-01'
SET @DateEnd=DATEADD(DAY,-1,DATEADD(MONTH,1,@DateBegin)) DECLARE @t table([日] varchar(3),[一] varchar(3),[二] varchar(3),[三] varchar(3),
[四] varchar(3),[五] varchar(3),[六] varchar(3)) WHILE @DateBegin<=@DateEnd
BEGIN
IF DATEPART(WEEKDAY,@DateBegin)=7 SET @Sun=RTRIM(DAY(@DateBegin))
IF DATEPART(WEEKDAY,@DateBegin)=1 SET @Mon=RTRIM(DAY(@DateBegin))
IF DATEPART(WEEKDAY,@DateBegin)=2 SET @Tue=RTRIM(DAY(@DateBegin))
IF DATEPART(WEEKDAY,@DateBegin)=3 SET @Wed=RTRIM(DAY(@DateBegin))
IF DATEPART(WEEKDAY,@DateBegin)=4 SET @Thu=RTRIM(DAY(@DateBegin))
IF DATEPART(WEEKDAY,@DateBegin)=5 SET @Fir=RTRIM(DAY(@DateBegin))
IF DATEPART(WEEKDAY,@DateBegin)=6 SET @Sta=RTRIM(DAY(@DateBegin))
IF @Sta<>'' --如果星期六不为空,那么说明一行已满开始新的一行。
BEGIN
INSERT INTO @t([日],[一],[二],[三],[四],[五],[六])VALUES(ISNULL(@Sun,''),ISNULL(@Mon,''),ISNULL(@Tue,''),ISNULL(@Wed,''),ISNULL(@Thu,''),ISNULL(@Fir,''),ISNULL(@Sta,''))
SET @Sun='';SET @Mon='';SET @Tue='';SET @Wed='';SET @Thu='';SET @Fir='';SET @Sta=''
END
SET @DateBegin=Dateadd(DAY,1,@DateBegin)
END
IF @Sun<>'' OR @Mon<>'' OR @Tue<>'' OR @Wed<>'' OR @Thu<>'' OR @Fir<>'' OR @Sta<>''
INSERT INTO @t([日],[一],[二],[三],[四],[五],[六])VALUES(ISNULL(@Sun,''),ISNULL(@Mon,''),ISNULL(@Tue,''),ISNULL(@Wed,''),ISNULL(@Thu,''),ISNULL(@Fir,''),ISNULL(@Sta,'')) SET datefirst 7
SELECT * FROM @t
SET NOCOUNT OFF
END --EXEC GetEveryDayOfMonth '2010-12-01' /*
日 一 二 三 四 五 六
---- ---- ---- ---- ---- ---- ----
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
*/ declare @dt datetime
set @dt = '2010-12-15' ;with t1 as
(
select dt = @dt-day(@dt)+number
from master..spt_values a
where type = 'P' and @dt-day(@dt)+number <= dateadd(m,1,@dt)-day(@dt) and number>0
)
,t2 as
(
select wk = substring(datename(weekday,dt),3,1), ww = datepart(week,dt),dd = day(dt) from t1
)
select * from t2 pivot (max(dd) for wk in ([日],[一],[二],[三],[四],[五],[六])) b /*
ww 日 一 二 三 四 五 六
----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
49 NULL NULL NULL 1 2 3 4
50 5 6 7 8 9 10 11
51 12 13 14 15 16 17 18
52 19 20 21 22 23 24 25
53 26 27 28 29 30 31 NULL (5 行受影响)
*/
declare @dt datetime
set @dt = '2010-12-15' ;with t1 as
(
select dt = @dt-day(@dt)+number
from master..spt_values a
where type = 'P' and @dt-day(@dt)+number <= dateadd(m,1,@dt)-day(@dt) and number>0
)
,t2 as
(
select wk = substring(datename(weekday,dt),3,1), ww = datepart(week,dt),dd = day(dt) from t1
)
select * from t2 pivot (max(dd) for wk in ([日],[一],[二],[三],[四],[五],[六])) b /*
ww 日 一 二 三 四 五 六
----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
49 NULL NULL NULL 1 2 3 4
50 5 6 7 8 9 10 11
51 12 13 14 15 16 17 18
52 19 20 21 22 23 24 25
53 26 27 28 29 30 31 NULL (5 行受影响)
*/
create function fn_calendar(@date datetime)
returns @t table (日 varchar(2), 一 varchar(2), 二 varchar(2), 三 varchar(2), 四 varchar(2), 五 varchar(2), 六 varchar(2))
as
begin
declare @offset int, @max int
set @date = convert(varchar(6), @date, 112) + ''
set @offset = (@@datefirst + datepart(weekday, @date) - 1) % 7
set @max = 33 - day(@date + 31)
declare @month table(id tinyint identity, date datetime, week tinyint)
insert @month select top 31 null, null from sysobjects
update @month set date = @date + id - 1, week = (id + @offset - 1) % 7
insert
@t
select
max(case week when 0 then ltrim(id) else '' end),
max(case week when 1 then ltrim(id) else '' end),
max(case week when 2 then ltrim(id) else '' end),
max(case week when 3 then ltrim(id) else '' end),
max(case week when 4 then ltrim(id) else '' end),
max(case week when 5 then ltrim(id) else '' end),
max(case week when 6 then ltrim(id) else '' end)
from
@month
where
id < @max
group by
(id + @offset - 1) / 7
return
end
go select * from fn_calendar('2008-05-01')
凑数娱乐: SQL code declare @dt datetime
set @dt='2010-12-15'
;with cte as(
select dateadd(dd,number-day(@dt)+1,@dt) dt
from master..spt_values
where type='p'
and month(@dt)=month(dateadd(dd,number-day(@dt)+1,@dt))and number<31
)
select [日],[一],[二],[三],[四],[五],[六] from(
select datepart(wk,dt)wk,right(datename(dw,dt),1)dw,day(dt)d from cte
)t pivot(max(d) for dw in([日],[一],[二],[三],[四],[五],[六]))b
/*
日 一 二 三 四 五 六
----------- ----------- ----------- ----------- ----------- ----------- -----------
NULL NULL NULL 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 NULL (5 行受影响)
*/
SQL做日历的更多相关文章
- oracle:如何用sql生成日历
BI分析中,经常需要将事实表与时间维度表关联起来,按年/月/日来逐层展示,常用的做法是创建一张日历表,结构类似如下: create table T_BAS_CALENDAR ( d_year ) no ...
- 从.net复制源代码中国农历阵列,必要做日历
从.net复制源代码中国农历阵列,必要做日历 const { 闰月的月份.春节的阳历日期(农历正月初一).农历的每一个月天数 } c_arrLunarInfo: array [1900 .. 2100 ...
- ORACLE应用调优:请避免SQL做大量循环逻辑处理
前阵子遇到一个案例:一个同事说以前一个运行很正常的包,突然间比以前慢了很多,执行时间非常长,晚上的作业调用这个包跑了几个小时也没有跑出数据.于是我在跟踪.优化过程中定位到包中一个存储过程的一段SQL, ...
- oracle里面用sql做报表并带小计合计常用到的函数
1-- DECODE函数是Oracle PL/SQL是功能强大的函数之一,假设我们想给职员加工资,其标准是:工资在8000元以下的将加20%:工资在8000元以上的加15%,通常的做法是,先选出记录 ...
- SQL查询日历
这东西给自己留着用. 经常会用到一些查询需要做全月统计,但有些时候的统计需要将未发生日期也显示出来,因此会需要一个固定的日期表,(T6的自定义查询估计也是需要的,至少以前是这样) 下面写两种方法来获取 ...
- HTML+JavaScript自己动手做日历
当我们需要在页面中显示某月的事项,或是选择某一段日期时,常常要使用到日历组件.这一组件同样有着许多现成的类库,然而亲自动手开发一个日历,从中了解其实现原理也是非常必要的.在本例中我们就将制作一款非常经 ...
- 还在写SQL做SAP二开?通过RFC调用NetWeaver,让HANA数据库操作更可靠
相比于从零开始构建全套信息化系统,基于成熟的ERP等行业软件做二次开发是更多中大型企业应对个性化软件需求的首选方案.如何在二开模块中,可靠地对成品软件的数据库进行读写操作,以满足单据自动创建.元数据自 ...
- 通过sql做数据透视表,数据库表行列转换(pivot和Unpivot用法)(一)
在mssql中大家都知道可以使用pivot来统计数据,实现像excel的透视表功能 一.MSsqlserver中我们通常的用法 1.Sqlserver数据库测试 ---创建测试表 Create tab ...
- 使用sql做迁移矩阵
在数据分析数据差异的时候 经常用到一个图叫做迁移矩阵. 其中里面的值可以是数量也可以是百分比,我们可以从一个时间点明确的看到在另一个时间点或者另一个时间点 子类之间数量迁移. 比如这次我在公司与业务核 ...
随机推荐
- iOS viewDidUnload方法
转自:http://blog.csdn.net/chun799/article/details/8951694 在iOS6中,viewDidUnload回调方法被Deprecated掉了.查看苹果的文 ...
- C++_归并排序(纯C版)
#include <iostream> #include <stdlib.h> using namespace std; int compared(const void *ke ...
- Linux编程之《守护进程》
Intro ----- 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常 ...
- 琐碎-hadoop1.X和2.X的区别
1. jobtracker做了分离,分成了resourceManager和nodemanager: 2. MR变成了和HBase和Hive等一样的yarn上面的一个应用: 3. 1.x的默认块大 ...
- python--json & pickle 模块
用于序列化的两个模块 json,用于字符串 和 python数据类型间进行转换 pickle,用于python特有的类型 和 python的数据类型间进行转换 Json模块提供了四个功能:dumps. ...
- 高德地图 JavaScript API 开发系列教程(一)
高德地图 API 提供包括 Web API 即 JavaScript API,Android API,定位API,IOS API,WP API,Win8 API等,本系列教程主要针对高德 JavaSc ...
- height、clientHeight、scrollHeight、offsetHeight区别
转自 http://www.cnblogs.com/yuteng/articles/1894578.html 我们来实现test中的onclick事件 function justAtest() ...
- 协议Protocol
1.协议:是一组声明方法的集合,不能声明成员变量,作用类似于接口. 遵守此协议的类就相当于拥有了这个协议的所有方法的声明,如果父类遵守了某个协议,子类也遵守了这个协议. ...
- python(4)-迭代器 和 生成器
迭代器是访问集合元素的一种方式.迭代器适合遍历一些巨大或无限的集合,比如几个G的文件.迭代器具有以下特点: 1. 访问者不需要关心迭代器内部的结构,只需通过__next__()方法不断取下一个内容 2 ...
- Linux系统root用户忘记密码解决方法
一:在linux系统启动时(如下图),按e键 二:进入到设置页面,定位到如下行: 三:按e键,进入输入界面 四:在编辑行最后面,空格,输入single,回车后回到第二步界面,只是后面多了single ...