2015-10-06 35 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

相關問題