Sql server 如何根据用户输入的日期获得输出更改?
我有3个输入表- 日水平Sql server 如何根据用户输入的日期获得输出更改?,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我有3个输入表- 日水平 Dim_type Id day_date month year 1 1 2015-01-05 January 2015
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
这显示了每周的基本数据。
周级
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
这显示了每月的基础数据
月平均水平
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_类型的列,它告诉我们哪些数据来自哪个表
dim_type=1 is for day level
dim_type=2 is for week level
dim_type=3 is for month level
在这里,我无法编写一个函数/过程,根据用户提供的输入日期,可以决定显示哪些数据-
这里我给您举一些例子,假设用户输入的日期为开始日期-2015-01-01和结束日期-2015-01-31。现在这里需要整个一月的数据,所以数据将来自月表。
第二个类似于开始日期-2015-01-05和结束日期-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,该id包含数据,该数据将根据日期过滤器在输出中表示。如何编写过滤代码是我需要帮助的部分
因此,我无法创建一个存储过程/函数,该存储过程/函数能够判断是否存在整月或逐周数据,或者是否应将其输出为日级别。有人能帮我吗?谢谢这将满足您的要求 有一些警告:函数将根据开始日期获取一个月的天数。
您应该将日期存储在数据库的月份表中,这样就不会一次又一次地重新创建临时表。 最好是聚合数据,这样就根本不需要使用此函数
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
创建过程GetDateParts
(
@开始日期,
@结束日期
)
作为
开始
/*要使用的变量*/
声明@Return VARCHAR(5)
/*
了解两个日期之间的差异
向值中添加1,以将第一天包括在计数中
*/
,@TotalNumberOfDays INT
,@daysinmonthtinyint;
/*表变量,用于存储一个月的天数
作为一个固定的SQL表,这会更好
大受欢迎*/
声明@Months表
([月]天[日]天);
/*月值*/
插入@Months
价值观
(1, 31),
(2, 28),
(3, 31),
(4, 30),
(5, 31),
(6, 30),
(7, 31),
(8, 31),
(9, 30),
(10, 31),
(11, 30),
(12, 31);
/*创建结果表*/
声明@resultable表([MonthNumber]TINYINT,[FullMonth]BIT,[Weeks]TINYINT,[Days]TINYINT)
--将计数设置为第位数
声明@Count TINYINT=MONTH(@StartDate);
设置@TotalNumberOfDays=DATEDIFF(天、@StartDate、@EndDate)+1
而@Count这将满足您的要求
有一些警告:函数将根据开始日期获取一个月的天数。
您应该将日期存储在数据库的月份表中,这样就不会一次又一次地重新创建临时表。
最好是聚合数据,这样就根本不需要使用此函数
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
创建过程GetDateParts
(
@开始日期,
@结束日期
)
作为
开始
/*要使用的变量*/
声明@Return VARCHAR(5)
/*
了解两个日期之间的差异
向值中添加1,以将第一天包括在计数中
*/
,@TotalNumberOfDays INT
,@daysinmonthtinyint;
/*表变量,用于存储一个月的天数
作为一个固定的SQL表,这会更好
大受欢迎*/
声明@Months表
([月]天[日]天);
/*月值*/
插入@Months
价值观
(1, 31),
(2, 28),
(3, 31),
(4, 30),
(5, 31),
(6, 30),
(7, 31),
(8, 31),
(9, 30),
(10, 31),
(11, 30),
(12, 31);
/*创建结果表*/
声明@resultable表([MonthNumber]TINYINT,[FullMonth]BIT,[Weeks]TINYINT,[Days]TINYINT)
--将计数设置为第位数
声明@Count TINYINT=MONTH(@StartDate);
设置@TotalNumberOfDays=DATEDIFF(天、@StartDate、@EndDate)+1
虽然@Count我已经创建了一个函数,它根据年、季或月为我们提供了聚合,但我被困在这里如何划分日期:(我不明白你想表达什么。你应该更好地定义业务逻辑。日期中的日、周和月表示什么?第二个和第三个例子令人困惑,事实上不是这样的……它只是表示一年中的第几周。我们没有周或月的日期,这就是我为什么这样写的原因e未添加每个表项都有一些数据,这些数据应该替换示例中的值我已经制作了一个函数,它根据年、季度或月为我们提供聚合,但我被困在这里如何划分日期:(我不明白你想表达什么。你应该更好地定义业务逻辑。日期中的日、周和月表示什么?第二个和第三个例子令人困惑,事实上不是这样的……它只是表示一年中的第几周。我们没有周或月的日期,这就是我为什么这样写的原因e未添加每个表项都有一些数据,这些数据应替换表中的值example@Aditya我确实考虑过这一点,以及如何处理这一点,但我没有