我希望在SQL Server数据库中创建一个视图。它将基于一个表格,如下所示:
Date (primary key) | Minimum (decimal) | Target (decimal) | Achieved (decimal)
随着一个月的进展,例如2015年1月,该表将每天填充。
我想创建一个看起来像这样的视图(比如说我们只到2015年1月2日):
2015-01-01 | Minimum | Target | Achieved | Calculated Column
2015-01-02 | Minimum | Target | Achieved | Calculated Column
2015-01-03 | null | null | null | Calculated Column
...
2015-01-31 | null | null | null | Calculated Column
因此,基本上从可用的表中返回数据,然后也为每个未来日添加一行。不要担心计算列,我想我可以做到这一点。
这有意义吗?感谢任何帮助。
谢谢。
答案 0 :(得分:2)
您可以生成一个日历表,其中包含所有感兴趣的日期。那么你只需要加入那个月的条件。有关如何制作日历表的信息,请参见this web site。有很多方法可以做到。
修改:根据此site,您可以在查询之前使用CTE创建要加入的临时日历:
declare @start datetime,
@end datetime
set @start = '2006-01-01'
set @end = '2007-01-01'
;
with calendar(date,isweekday, y, q,m,d,dw,monthname,dayname,w) as
(
select @start ,
case when datepart(dw,@start) in (1,7) then 0 else 1 end,
year(@start),
datepart(qq,@start),
datepart(mm,@start),
datepart(dd,@start),
datepart(dw,@start),
datename(month, @start),
datename(dw, @start),
datepart(wk, @start)
union all
select date + 1,
case when datepart(dw,date + 1) in (1,7) then 0 else 1 end,
year(date + 1),
datepart(qq,date + 1),
datepart(mm,date + 1),
datepart(dd,date + 1),
datepart(dw,date + 1),
datename(month, date + 1),
datename(dw, date + 1),
datepart(wk, date + 1) from calendar where date + 1< @end
)
select * from calendar option(maxrecursion 10000)
答案 1 :(得分:0)
根据您的问题,显然您需要使用存储过程或函数,因为您的输出必须具有结束日期。基本上,您需要一个接受日期参数的存储过程或函数,并输出包含所需数据的表。类似于以下内容可能会有所帮助:
USE TEST -- Test database. You may want to replace this with your DB name
GO
CREATE PROCEDURE proStackOverflowQuestion25287207 @date date -- To try it, execute: exec proStackOverflowQuestion25287207 '2008-02-11' -- or any date of your choice.
AS
BEGIN
DECLARE @monthdays INT, @dateday INT, @marker INT, @noRecordDate NVARCHAR(30)
SET @marker = 1 -- we start the first day of the month
SET @monthdays = DATEDIFF(dd,@date,(DATEADD(mm,1,@date))) -- get the number of days in the concerned month
SET @dateday = DAY(@date)
CREATE TABLE #temTbl(
[Date] [date] PRIMARY KEY,
[Minimum] [decimal](18, 0) NULL,
[Target] [decimal](18, 0) NULL,
[Achieved] [decimal](18, 0) NULL,
[Calculated] [decimal](18, 0) NULL
)
WHILE @marker <= @monthdays
BEGIN
--insert new record in temp table
IF exists(SELECT * FROM MyTable WHERE DAY([Date]) = @marker AND MONTH([Date]) = MONTH(@date) AND YEAR([Date]) = YEAR(@date))
INSERT INTO #temTbl SELECT *, null FROM MyTable WHERE DAY([Date]) = @marker --*** you may need to replace null by your Calculated value...
ELSE
BEGIN
SET @noRecordDate = CONVERT(NVARCHAR(4), YEAR(@date)) + '-' + CONVERT(NVARCHAR(2), MONTH(@date)) + '-' + CONVERT(NVARCHAR(2), @marker)
INSERT INTO #temTbl([Date], Minimum, [Target], Achieved, Calculated) VALUES (@noRecordDate, null, null, null, null) -- you may need to replace the last null by your calculated value...
END
-- increment marker
SET @marker = @marker + 1
END
SELECT * FROM #temTbl
END