Sql server 如何根据用户输入的日期获得输出更改?

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

我有3个输入表- 日水平

   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我确实考虑过这一点,以及如何处理这一点,但我没有