我有3个输入表 - day_level
Dim_type Id day_date month year
1 1 2015-01-05 January 2015
1 2 2015-01-06 January 2015
1 3 2015-01-07 January 2015
1 4 2015-01-08 January 2015
1 5 2015-01-09 January 2015
1 6 2015-01-10 January 2015
1 7 2015-01-11 January 2015
1 8 2015-01-12 January 2015
1 9 2015-01-13 January 2015
1 10 2015-01-14 January 2015
1 11 2015-01-15 January 2015
1 12 2015-01-16 January 2015
1 13 2015-01-17 January 2015
1 14 2015-01-18 January 2015
1 15 2015-01-19 January 2015
1 16 2015-01-20 January 2015
显示每周基础数据。 week_level
Dim_type Id week_number month year
2 101 week1 January 2015
2 102 week2 January 2015
2 103 week3 January 2015
2 104 week4 January 2015
2 105 week1 February 2015
显示每月基础数据。
month_level
Dim_type Id month year
3 1001 January 2015
3 1002 January 2015
3 1003 January 2015
3 1004 January 2015
3 1005 February 2015
我有3个表,其中包含根据日级,周级和月级的数据。有Dim_type列告诉我们哪个数据来自哪个表
dim_type=1 is for day level
dim_type=2 is for week level
dim_type=3 is for month level
在这里,我无法编写一个函数/程序,根据用户给出的输入日期,可以决定显示哪些数据 -
这里我举一些例子,假设用户start date- 2015-01-01 and end date- 2015-01-31
输入日期。现在这里需要整个1月份的数据,因此数据将来自月份表。
其次是start date-2015-01-05 and end date- 2015-01-06
。现在我们在任何一方都没有完整的月份,所以在这里我们必须考虑周数据。所以这里的输出就像 -
id value
102 week2 ( January)
103 week3 ( ,, )
104 week4 ( ,, )
105 week5 (Febuaray)
这里考虑整周,因为周六和周日都是非工作日。
第三个就像开始日期 - 2015-01-05和结束日期 - 2015-01-20所以它就像
id value
102 week2 ( January)
103 week3 ( ,, )
14 day level data for 18 January
15 day level data for 19 January
12 day level data for 20 January
每个表id都有唯一的id,它有数据,这个数据根据日期过滤器在输出中表示。如何编写过滤器代码是我需要帮助的部分!
所以我无法创建一个存储过程/函数来判断是否存在整月或每周数据,或者它应该作为日级输出。谁能帮我?谢谢
答案 0 :(得分:0)
这将满足您的要求。
有一些警告:该功能将根据开始日期获得一个月内的天数 您应该将日期存储在数据库中的月份表中,这样您就不会一次又一次地重新创建临时表。 你最好聚合数据,这样就根本不需要使用这个功能。
CREATE FUNCTION dbo.ISFullMonth (@StartDate DATE, @EndDate DATE)
RETURNS VARCHAR(5)
BEGIN
/* variables to be used */
DECLARE @Return VARCHAR(5), @Difference INT, @DaysInMonth TINYINT;
/*
table variable to store the number of days in a month
this would be better as a fixed SQL table as it'll
be called a lot
*/
DECLARE @Months TABLE
([Month] TINYINT, [NoDays] TINYINT);
/*
month values
*/
INSERT INTO @Months
VALUES
(1, 31),
(2, 28),
(3, 31),
(4, 30),
(5, 31),
(6, 30),
(7, 31),
(8, 31),
(9, 30),
(10, 31),
(11, 30),
(12, 31);
/*
get the number of days in the month
*/
SELECT @DaysInMonth = [NoDays] FROM @Months WHERE [Month] = MONTH(@StartDate);
/*
Check if it's a leap year and alter the number of days in Febuary to 29
This was taken from https://www.mssqltips.com/sqlservertip/1527/sql-server-function-to-determine-a-leap-year/
*/
IF((SELECT CASE DATEPART(mm, DATEADD(dd, 1, CAST((CAST(@StartDate AS VARCHAR(4)) + '0228') AS DATE)))
WHEN 2 THEN 1
ELSE 0
END) = 1) AND MONTH(@StartDate) = 2
SET @DaysInMonth = 29;
/*
Get the difference between the two dates
add 1 to the value to include the first day in the count
*/
SET @Difference = DATEDIFF(day, @StartDate, @EndDate)+1;
/*
Check how many days difference there are
*/
If (@Difference >= @DaysInMonth)
BEGIN
SET @Return = 'Month';
END
ELSE IF (@Difference > 7)
BEGIN
SET @Return = 'Week';
END
ELSE
BEGIN
SET @Return = 'Day';
END
RETURN @Return;
END
GO
好的,写作的时间比我预期的要长,但是你走了。这应该适用于现在,但它根本没有完全走过几年。
CREATE PROCEDURE GetDateParts
(
@StartDate DATE ,
@EndDate DATE
)
AS
BEGIN
/* variables to be used */
DECLARE @Return VARCHAR(5)
/*
Get the difference between the two dates
add 1 to the value to include the first day in the count
*/
, @TotalNumberOfDays INT
, @DaysInMonth TINYINT;
/* table variable to store the number of days in a month
this would be better as a fixed SQL table as it'll
be called a lot */
DECLARE @Months TABLE
([Month] TINYINT, [NoDays] TINYINT);
/* month values */
INSERT INTO @Months
VALUES
(1, 31),
(2, 28),
(3, 31),
(4, 30),
(5, 31),
(6, 30),
(7, 31),
(8, 31),
(9, 30),
(10, 31),
(11, 30),
(12, 31);
/* Create Result table */
DECLARE @ResultTable TABLE ([MonthNumber] TINYINT, [FullMonth] BIT, [Weeks] TINYINT, [Days] TINYINT)
-- set the count as the mointh number
DECLARE @Count TINYINT = MONTH(@StartDate);
SET @TotalNumberOfDays = DATEDIFF(day, @StartDate, @EndDate)+1
WHILE @Count <= MONTH(@EndDate)
BEGIN
/* get the number of days in the month */
SELECT @DaysInMonth = [NoDays] FROM @Months WHERE [Month] = @Count;
/*
Check if it's a leap year and alter the number of days in Febuary to 29
This was taken from https://www.mssqltips.com/sqlservertip/1527/sql-server-function-to-determine-a-leap-year/
*/
IF((SELECT CASE DATEPART(mm, DATEADD(dd, 1, CAST((CAST(@StartDate AS VARCHAR(4)) + '0228') AS DATE)))
WHEN 2 THEN 1
ELSE 0
END) = 1) AND MONTH(@StartDate) = 2
SET @DaysInMonth = 29;
IF (@TotalNumberOfDays >= @DaysInMonth)
BEGIN
INSERT INTO @ResultTable ([MonthNumber], [FullMonth])
VALUES (@Count, 1)
SET @TotalNumberOfDays = @TotalNumberOfDays - (@DaysInMonth-DAY(@StartDate));
SET @StartDate = DATEADD(day, (@DaysInMonth-DAY(@StartDate)+1), @StartDate);
SET @Count = @Count + 1;
END
ELSE IF (@TotalNumberOfDays >= 7)
BEGIN
INSERT INTO @ResultTable ([MonthNumber], [Weeks])
VALUES (@Count, CAST(@TotalNumberOfDays/7 AS INT))
DECLARE @Remainder TINYINT = @TotalNumberOfDays%7;
IF (@Remainder = 0)
BEGIN
SET @Count = @Count + 1;
END
ELSE
BEGIN
SET @TotalNumberOfDays = @Remainder;
END
END
ELSE
BEGIN
INSERT INTO @ResultTable ([MonthNumber], [Days])
VALUES (@Count, @TotalNumberOfDays)
SET @Count = @Count + 1;
END
END;
-- Return Results
SELECT * FROM @ResultTable;
END