2015-10-06 196 views
1

我有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=1 is for day level 

dim_type=2 is for week level 

dim_type=3 is for month level 

在这里,我不能写一个函数/过程由用户给定的输入日期的基础上,可以决定哪些数据是Dim_type列待显示 -

这里我给你举一些例子,假设用户输入的日期为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年1月5日,结束日期 - 二零一五年一月二十零日所以它会像

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

我不明白你想要什么你应该更好地定义业务逻辑,日期,星期和月份的级别代表日期?第二个和第三个例子令人困惑 – tobypls

+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 
+0

@Aditya的数据,我确实想过这个以及如何可以处理,但问题的措辞表明OP只想知道一个月。但是将其改为存储过程可以很容易地返回一个包含数月,数周和数天的表格。 – Guy

+0

这就是我想知道的一切:(我不能这样做......请你帮忙!!! –

+0

是的,但我现在在火车上,以后可以重新写作sp。 – Guy