我需要生成一个报告,该报告将显示7个星期一到星期日和5个行,就像正常的月历一样:
我需要列表中的日期,所以欲望表结果应如下所示:
这样我的报表设计师就会自动创建如上所示的视图。
上面的表结果应该是动态生成的,不需要任何数据库表,因为在此之后我将不得不将日期连接到我的一个数据库表,这样我就可以填充我将用于的其他类型的信息在我的报告中显示每一天。
有任何线索吗?
答案 0 :(得分:2)
任意日期序列的SQL小提琴,不需要表格。
http://sqlfiddle.com/#!3/9eecb7/275
DECLARE @dtStartDate datetime
DECLARE @dtEndDate datetime
SET @dtStartDate = '2015-05-01'
SET @dtEndDate = '2015-05-31'
SELECT
CASE DATEPART(weekday, T.DateVal)
WHEN 1 THEN 'Sunday'
WHEN 2 THEN 'Monday'
WHEN 3 THEN 'Tuesday'
WHEN 4 THEN 'Wednesday'
WHEN 5 THEN 'Thursday'
WHEN 6 THEN 'Friday'
WHEN 7 THEN 'Saturday'
END AS WeekDay,
DATEPART(day, T.DateVal) AS [Date],
DATEPART(month, T.DateVal) AS [Month],
DATEPART(year, T.DateVal) AS [Year]
FROM
(
SELECT
DATEADD(day, SEQ.SeqValue, @dtStartDate) DateVal
FROM
(
SELECT
(HUNDREDS.SeqValue + TENS.SeqValue + ONES.SeqValue) SeqValue
FROM
(
SELECT 0 SeqValue
UNION ALL
SELECT 1 SeqValue
UNION ALL
SELECT 2 SeqValue
UNION ALL
SELECT 3 SeqValue
UNION ALL
SELECT 4 SeqValue
UNION ALL
SELECT 5 SeqValue
UNION ALL
SELECT 6 SeqValue
UNION ALL
SELECT 7 SeqValue
UNION ALL
SELECT 8 SeqValue
UNION ALL
SELECT 9 SeqValue
) ONES
CROSS JOIN
(
SELECT 0 SeqValue
UNION ALL
SELECT 10 SeqValue
UNION ALL
SELECT 20 SeqValue
UNION ALL
SELECT 30 SeqValue
UNION ALL
SELECT 40 SeqValue
UNION ALL
SELECT 50 SeqValue
UNION ALL
SELECT 60 SeqValue
UNION ALL
SELECT 70 SeqValue
UNION ALL
SELECT 80 SeqValue
UNION ALL
SELECT 90 SeqValue
) TENS
CROSS JOIN
(
SELECT 0 SeqValue
UNION ALL
SELECT 100 SeqValue
UNION ALL
SELECT 200 SeqValue
UNION ALL
SELECT 300 SeqValue
UNION ALL
SELECT 400 SeqValue
UNION ALL
SELECT 500 SeqValue
UNION ALL
SELECT 600 SeqValue
UNION ALL
SELECT 700 SeqValue
UNION ALL
SELECT 800 SeqValue
UNION ALL
SELECT 900 SeqValue
) HUNDREDS
) SEQ
) T
WHERE
T.DateVal <= @dtEndDate
ORDER BY
T.DateVal ASC
答案 1 :(得分:0)
编辑添加开始空白日期。如有必要,可以使用相同的逻辑附加空白日期。
declare @begindate date = '5-1-2015'
declare @enddate date = '6-1-2015'
create table MyCal (MyWeekday varchar(10), MyDate varchar(2), MyMonth varchar(10), MyYear int)
declare @DaysFromMonday int =
case datepart(weekday, @begindate)
when 1 then 6
else datepart(weekday, @begindate) - 2
end
declare @datecounter date = dateadd(dd, -1* @daysFromMonday, @begindate)
while @datecounter < @enddate
begin
insert into MyCal values (
datename(weekday, @datecounter)
, case when @datecounter < @begindate then '' else cast(datepart(DD, @datecounter) as varchar) end
, datename(month, @datecounter)
, datepart(YYYY, @datecounter)
)
set @datecounter = dateadd(day, 1, @datecounter)
end
select * from MyCal
答案 2 :(得分:0)
您可以使用这段代码。 将#tmp表替换为您喜欢的正确表名。
declare @start_date datetime, @end_date datetime, @cur_date datetime
set @start_date = '2015-05-01'
set @end_date = '2016-04-30'
set @cur_date = @start_date
create table #tmp
(weekday varchar(10),
date int,
month varchar(10),
year int)
while @cur_date <= @end_date
begin
insert into #tmp
select datename(dw, @cur_date), datepart(day, @cur_date), datename(month, @cur_date), datepart(year, @cur_date)
set @cur_date = dateadd(dd, 1, @cur_date)
end
select * from #tmp
drop table #tmp
答案 3 :(得分:0)
试试此版本 - 您必须一次运行一个月。如果这个月的最后一天不是星期天,我还添加了空白,例如试试他2015年8月。
declare @start_date datetime, @end_date datetime, @cur_date datetime
set @start_date = '2015-05-01'
set @end_date = '2015-05-31'
set @cur_date = @start_date
create table #tmp
(weekday varchar(10),
date varchar(2),
month varchar(10),
year int)
while datepart(dw, @cur_date) > 2
begin
insert into #tmp
select datename(dw, dateadd(dd, -(datepart(dw, @cur_date) - 2), @start_date)), '', datename(month, @start_date), datepart(year, @start_date)
set @cur_date = dateadd(dd, -1, @cur_date)
end
set @cur_date = @start_date
while @cur_date <= @end_date
begin
insert into #tmp
select datename(dw, @cur_date), datepart(day, @cur_date), datename(month, @cur_date), datepart(year, @cur_date)
set @cur_date = dateadd(dd, 1, @cur_date)
end
set @cur_date = @end_date
while datepart(dw, @cur_date) > 1
begin
insert into #tmp
select datename(dw, dateadd(dd, 1, @cur_date)), '', datename(month, @end_date), datepart(year, @end_date)
set @cur_date = dateadd(dd, 1, @cur_date)
end
select * from #tmp
drop table #tmp
希望这有帮助。
答案 4 :(得分:0)
以下是使用multiple CTE查询和使用EMONTH SQL函数的SQL DATENAME月末函数的替代方法
declare @date as date = dateadd(mm,0,getdate())
;with monthdates as (
SELECT dateadd(dd,1,EOMONTH(dateadd(mm,-1,@date))) firstofmonth, EOMONTH (@date) lastofmonth
), calc as (
select
firstofmonth, lastofmonth,
dateadd(dd,
-1 * case when datepart(dw,firstofmonth)-2 >= 0 then datepart(dw,firstofmonth)-2 else datepart(dw,firstofmonth)+7-2 end,
firstofmonth
) firstofcalendar,
datediff(WEEK,
dateadd(dd,
-1 * case when datepart(dw,firstofmonth)-2 >= 0 then datepart(dw,firstofmonth)-2 else datepart(dw,firstofmonth)+7-2 end,
firstofmonth
),
lastofmonth) weekcount
from monthdates
), calendar1 as (
select
firstofcalendar,
firstofmonth,
lastofmonth,
case when dateadd(dd, weekcount * 7 - 1, firstofcalendar) = lastofmonth then lastofmonth
else
dateadd(dd, (weekcount+1) * 7 - 1, firstofcalendar)
end as lastofcalendar
from calc
), calendar as (
select
datename(dw,date) dayname,
case when month(date) = month(@date) then cast(cast(date as date) as nvarchar) else '' end as date
from calendar1
cross apply [dbo].[DateTable](firstofcalendar, lastofcalendar)
)
select *, datename(mm,@date) month, datepart(yyyy,@date) year from calendar
答案 5 :(得分:-1)
这样的事应该适合你。它应该适用于您选择的任何一周开始:您只需要{/ 3}}连接/查询以适应。如果您希望星期一开始,请使用set datefirst 1
。
以下是查询:
set datefirst = 1 -- start the week on Monday
declare @month date = '1 May 2015'
;with
month_days as
(
select dd = -5 union all
select dd = -4 union all
select dd = -3 union all
select dd = -2 union all
select dd = -1 union all
select dd = 0 union all
select dd = 1 union all
select dd = 2 union all
select dd = 3 union all
select dd = 4 union all
select dd = 5 union all
select dd = 6 union all
select dd = 7 union all
select dd = 8 union all
select dd = 9 union all
select dd = 10 union all
select dd = 11 union all
select dd = 12 union all
select dd = 13 union all
select dd = 14 union all
select dd = 15 union all
select dd = 16 union all
select dd = 17 union all
select dd = 18 union all
select dd = 19 union all
select dd = 20 union all
select dd = 21 union all
select dd = 22 union all
select dd = 23 union all
select dd = 24 union all
select dd = 25 union all
select dd = 26 union all
select dd = 27 union all
select dd = 28 union all
select dd = 29 union all
select dd = 30 union all
select dd = 31 union all
select dd = 32 union all
select dd = 33 union all
select dd = 34 union all
select dd = 35 union all
select dd = 36 union all
select dd = 37
),
calendar as
(
select * ,
yyyymmdd = dateadd(day,t.dd-1,@month)
from month_days t
)
select Day_Of_Week = datename(weekday,c.yyyymmdd ) ,
DD = datepart(day , c.yyyymmdd ) ,
MM = datepart(month , c.yyyymmdd ) ,
YYYY = datepart(year , c.yyyymmdd )
from calendar c
where datediff(month,@month,c.yyyymmdd) = 0 -- current month
OR ( datediff(month,@month,c.yyyymmdd) < 0 -- previous month
and datepart(weekday,c.yyyymmdd) < datepart(weekday,@month) ) -- ...to pad out the first week
OR ( datediff(month,@month,c.yyyymmdd) > 0 -- next month
and datepart(weekday,c.yyyymmdd) >= datepart(weekday,dateadd(month,1,@month)) -- ... to pad out the last week
)
order by c.yyyymmdd
运行上述查询会产生预期的
Day_Of_Week DD MM YYYY
=========== == == ====
Monday 27 4 2015
Tuesday 28 4 2015
Wednesday 29 4 2015
Thursday 30 4 2015
Friday 1 5 2015
Saturday 2 5 2015
Sunday 3 5 2015
Monday 4 5 2015
Tuesday 5 5 2015
Wednesday 6 5 2015
Thursday 7 5 2015
Friday 8 5 2015
Saturday 9 5 2015
Sunday 10 5 2015
Monday 11 5 2015
Tuesday 12 5 2015
Wednesday 13 5 2015
Thursday 14 5 2015
Friday 15 5 2015
Saturday 16 5 2015
Sunday 17 5 2015
Monday 18 5 2015
Tuesday 19 5 2015
Wednesday 20 5 2015
Thursday 21 5 2015
Friday 22 5 2015
Saturday 23 5 2015
Sunday 24 5 2015
Monday 25 5 2015
Tuesday 26 5 2015
Wednesday 27 5 2015
Thursday 28 5 2015
Friday 29 5 2015
Saturday 30 5 2015
Sunday 31 5 2015
Monday 1 6 2015
Tuesday 2 6 2015
Wednesday 3 6 2015
Thursday 4 6 2015
Friday 5 6 2015
Saturday 6 6 2015