2014-10-22 42 views

回答

2

你可以做在SQL Server中是這樣的:

DECLARE @BaseDate DATE = '20111107'; 
DECLARE @EndDate DATE = GETDATE(); --Or the "end of dates in the database" 
WITH RecursiveCTE AS (
    SELECT 
     1 AS [Counter], 
     @BaseDate AS [MyDate] 
    UNION ALL 
    SELECT 
     [Counter] + 1, 
     DATEADD(DAY, 7, MyDate) 
    FROM 
     RecursiveCTE 
    WHERE 
     MyDate < @EndDate) 
SELECT * FROM RecursiveCTE OPTION (MAXRECURSION 0); 

處理日期未準確,使這成爲一個功能,你可以這樣做:

--Function definition 
CREATE FUNCTION SuperDuperDataCalculator (
    @BaseDate DATE = '20131016', 
    @EndDate DATE = '20131020') 
RETURNS @Results TABLE (
    [Counter] INT, 
    [Date] DATE) 
AS 
BEGIN 
    WITH RecursiveCTE AS (
     SELECT 
      1 AS [Counter], 
      @BaseDate AS [MyDate] 
     UNION ALL 
     SELECT 
      [Counter] + 1, 
      CASE WHEN DATEADD(DAY, 7, MyDate) > @EndDate THEN @EndDate ELSE DATEADD(DAY, 7, MyDate) END 
     FROM 
      RecursiveCTE 
     WHERE 
      MyDate < @EndDate) 
    INSERT INTO 
     @Results 
    SELECT * FROM RecursiveCTE OPTION (MAXRECURSION 0); 
    RETURN; 
END; 
GO 

--Usage 
SELECT * FROM SuperDuperDataCalculator('20131016', '20131020'); 

--Results 
Counter Date 
1 2013-10-16 
2 2013-10-20 

請注意,我們必須使用多語句表值函數,因爲在SQL Server中的錯誤,它不會讓你用一個簡單的表值函數的選擇。另一種方法是從函數中刪除OPTION(MAXRECURSION 0),並記住在每次引用它時使用它(即相當差的選擇)。

...最後,如果你想只返回計數器值的最大值,你可以重寫這是一個標量值函數,即:

--Function definition 
CREATE FUNCTION SuperDuperDataCalculator (
    @BaseDate DATE = '20131016', 
    @EndDate DATE = '20131020') 
RETURNS INT 
AS 
BEGIN 
    DECLARE @Results TABLE (
    [Counter] INT, 
    [Date] DATE); 
    DECLARE @ReturnValue INT; 
    WITH RecursiveCTE AS (
     SELECT 
      1 AS [Counter], 
      @BaseDate AS [MyDate] 
     UNION ALL 
     SELECT 
      [Counter] + 1, 
      CASE WHEN DATEADD(DAY, 7, MyDate) > @EndDate THEN @EndDate ELSE DATEADD(DAY, 7, MyDate) END 
     FROM 
      RecursiveCTE 
     WHERE 
      MyDate < @EndDate) 
    INSERT INTO 
     @Results 
    SELECT * FROM RecursiveCTE OPTION (MAXRECURSION 0); 
    SELECT @ReturnValue = MAX([Counter]) FROM @Results; 
    RETURN @ReturnValue; 
END; 
GO 
SELECT dbo.SuperDuperDataCalculator('20131016', '20131020'); 
+0

如果結束日期是可以說20/10/2013我BaseDate(RecursiveCTE被調用後)爲16/10/2013,則函數應該考慮到20/10後停止/2013.it不應該增加7〜16/10/2013.do我需要檢查過 – newbie 2014-10-22 17:19:29

+0

我補充說,包括這 – 2014-10-23 08:12:31

+0

感謝您的回覆一個新的腳本日期之間的間隔。但它應該添加4至16/10/2013它必須考慮數據庫中的所有日期,在這種情況下是2013年10月20日。我需要一個函數,這樣我可以用書面的Visual Studio C#。我是不知道的SQL查詢的功能名稱,但我在SQL想我們需要寫CREATE FUNCTION Funtionname聲明函數 – newbie 2014-10-23 08:52:47

0

試試這個 - 這將讓所有的周在子查詢中分配一個rownumber。然後只選擇行號= 1的記錄,因爲該周可能會有更多結果。所以因此RowNo = 1

SELECT ROW_NUMBER() OVER(ORDER BY RowNo) AS IncrementalWeek,dte 
FROM 
(
     SELECT DISTINCT DATEPART(ww,CONVERT(VARCHAR(20),createdDate,111)) AS [week], 
         CONVERT(VARCHAR(20),createdDate,111) AS dte, 
         ROW_NUMBER() OVER(PARTITION BY DATEPART(ww,Convert(VARCHAR(20),createdDate,111)) ORDER BY DATEPART(ww,CONVERT(VARCHAR(20),createdDate,111))) AS RowNo 
     FROM YourTable 

) AS tble 
WHERE RowNo = 1 
ORDER BY [week]