Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server以月为单位拆分日期范围_Sql_Sql Server - Fatal编程技术网

SQL Server以月为单位拆分日期范围

SQL Server以月为单位拆分日期范围,sql,sql-server,Sql,Sql Server,我想将日期范围分为几个月。我将通过startdate1-jan-2011和enddate31-dec-2011作为参数,然后它必须返回如下结果 1-jan-2011 - 31-jan-2011 1-feb-2011 - 28-feb-2011 1-mar-2011 - 31-mar-2011 请给我发一个存储过程 谢谢, 阿披实试试这个: CREATE PROC SplitDateRange @from DATETIME, @to DATETIME AS BEGIN S

我想将日期范围分为几个月。我将通过startdate1-jan-2011和enddate31-dec-2011作为参数,然后它必须返回如下结果

1-jan-2011 - 31-jan-2011
1-feb-2011 - 28-feb-2011
1-mar-2011 - 31-mar-2011

请给我发一个存储过程

谢谢, 阿披实

试试这个:

CREATE PROC SplitDateRange
    @from DATETIME,
    @to DATETIME
AS
BEGIN
    SET NOCOUNT ON;

    SET @from = CONVERT(VARCHAR, DATEADD(DAY, -DATEPART(DAY, @from)+1, @from), 112)

    -- Sql 2000

    CREATE TABLE #temp (DateFrom DATETIME, DateTo DATETIME)
    WHILE @from < @to
    BEGIN
        INSERT #temp VALUES (@from, DATEADD(DAY, -1, DATEADD(MONTH, 1, @from)))
        SET @from = DATEADD(MONTH, 1, @from)
    END

    SELECT * FROM #temp
    DROP TABLE #temp


    --sql 2005+
    /*
    ;WITH Ranges(DateFrom, DateTo) AS
    (
        SELECT @from DateFrom, DATEADD(DAY, -1, DATEADD(MONTH, 1, @from)) DateTo
        UNION ALL
        SELECT DATEADD(MONTH, 1, DateFrom), DATEADD(DAY, -1, DATEADD(MONTH, 1, DATEADD(MONTH, 1, DateFrom)))
        FROM Ranges
        WHERE DateFrom < DATEADD(MONTH, -1, @To)
    )
    SELECT * FROM Ranges
    OPTION(MAXRECURSION 0)
    */
END
GO
EXEC SplitDateRange '2011-01-02', '2012-06-06'
试试这个:

CREATE PROC SplitDateRange
    @from DATETIME,
    @to DATETIME
AS
BEGIN
    SET NOCOUNT ON;

    SET @from = CONVERT(VARCHAR, DATEADD(DAY, -DATEPART(DAY, @from)+1, @from), 112)

    -- Sql 2000

    CREATE TABLE #temp (DateFrom DATETIME, DateTo DATETIME)
    WHILE @from < @to
    BEGIN
        INSERT #temp VALUES (@from, DATEADD(DAY, -1, DATEADD(MONTH, 1, @from)))
        SET @from = DATEADD(MONTH, 1, @from)
    END

    SELECT * FROM #temp
    DROP TABLE #temp


    --sql 2005+
    /*
    ;WITH Ranges(DateFrom, DateTo) AS
    (
        SELECT @from DateFrom, DATEADD(DAY, -1, DATEADD(MONTH, 1, @from)) DateTo
        UNION ALL
        SELECT DATEADD(MONTH, 1, DateFrom), DATEADD(DAY, -1, DATEADD(MONTH, 1, DATEADD(MONTH, 1, DateFrom)))
        FROM Ranges
        WHERE DateFrom < DATEADD(MONTH, -1, @To)
    )
    SELECT * FROM Ranges
    OPTION(MAXRECURSION 0)
    */
END
GO
EXEC SplitDateRange '2011-01-02', '2012-06-06'

因此,您可以在另一个SQL查询中使用结果,我假设这是您要去的地方,我将把它放入一个表值函数中

假设SQL Server 2005+您可以使用此

CREATE FUNCTION dbo.ufnMonthlyIntervals(
                  @from_date SMALLDATETIME,
                  @end_date  SMALLDATETIME
)
RETURNS TABLE
WITH
  intervals (
    from_date,
    end_date
  )
AS
(
  SELECT @from_date,   DATEADD(MONTH, 1, @from_date  ) - 1
  UNION ALL
  SELECT end_date + 1, DATEADD(MONTH, 1, end_date + 1) - 1 FROM intervals WHERE end_date < @end_date
)
RETURN
  SELECT
    from_date,
    CASE WHEN end_date > @end_date THEN @end_date ELSE end_date END AS end_date
  FROM
    intervals

然后您只需使用SELECT*FROM dbo.UFNMonthlyInterval'20110101',20111201'作为间隔

,这样您就可以在另一个SQL查询中使用结果,我假设这就是您要去的地方,我会将其放入表值函数中

假设SQL Server 2005+您可以使用此

CREATE FUNCTION dbo.ufnMonthlyIntervals(
                  @from_date SMALLDATETIME,
                  @end_date  SMALLDATETIME
)
RETURNS TABLE
WITH
  intervals (
    from_date,
    end_date
  )
AS
(
  SELECT @from_date,   DATEADD(MONTH, 1, @from_date  ) - 1
  UNION ALL
  SELECT end_date + 1, DATEADD(MONTH, 1, end_date + 1) - 1 FROM intervals WHERE end_date < @end_date
)
RETURN
  SELECT
    from_date,
    CASE WHEN end_date > @end_date THEN @end_date ELSE end_date END AS end_date
  FROM
    intervals

然后您只需使用SELECT*FROM dbo.ufnmonthlyInterval'20110101',20111201'作为间隔

请给我发送一个存储过程-您尝试了什么?请给我发送一个存储过程-您尝试了什么?@AndriyM-请参阅中的第二个示例作为我的语法参考。是,我明白,如果一个人不密切注意,这会产生误导RETURNS TABLE和[AS]RETURN之间的WITH子句与CTE定义无关。@AndriyM-请参阅AS参考中的第二个示例以了解我的语法。是的,我知道如果不密切注意,它可能会产生误导:RETURNS TABLE和[AS]RETURN之间的WITH子句与CTE定义无关。