【问题标题】:Get dates between date of ID and date of plus or minus days获取 ID 日期和正负天数之间的日期
【发布时间】:2020-04-06 14:56:19
【问题描述】:

我有以下示例数据:

CREATE TABLE tblDates
(
    ID int,
    Dates DATE
);

SELECT * FROM tblDates

INSERT INTO tblDates VALUES(1,'2019-12-01');
INSERT INTO tblDates VALUES(2,'2019-12-05');
INSERT INTO tblDates VALUES(3,'2019-12-02');
INSERT INTO tblDates VALUES(4,'2019-12-09');
INSERT INTO tblDates VALUES(5,'2019-12-11');

在这里,我正在寻找 dateID = 4 之间的日期,以及 1,2,....n 天之间的日期。

尝试 1:我尝试使用 UNION ALL。

SELECT Dates FROM tblDates WHERE ID = 4 
UNION ALL
SELECT DATEADD(day,1,Dates) FROM tblDates WHERE ID = 4;

当我正在寻找 50 天或更多天数的差异时,这种方法并不适用。

尝试2:

SELECT Dates FROM tblDates WHERE ID = 4 AND Dates between Dates AND DATEADD(day,1,Dates);

有单身约会。

尝试3:

创建的函数:获取日期的函数

CREATE FUNCTION udf_GetDates(@MinDate DATE,@MaxDate DATE)
RETURNS TABLE
AS
RETURN
SELECT  TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
        Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate)
FROM    sys.all_objects a
        CROSS JOIN sys.all_objects b;

查询:

SELECT f.* 
FROM udf_GetDates(t.Dates,DATEADD(day,1,t.Dates)) f        
INNER JOIN tblDates t ON f.[Date] = t.[Dates]
WHERE t.ID = 4

出现错误:

Msg 4104, Level 16, State 1, Line 2 多部分标识符 无法绑定“t.Dates”。消息 4104,第 16 级,状态 1,第 2 行 无法绑定多部分标识符“t.Dates”。

预期输出:

给定:ID = 4 和 day=+1

Dates
----------- 
2019-12-09
2019-12-10

给定:ID = 4 和 day=+10

Dates
----------- 
2019-12-09
2019-12-10
2019-12-11
2019-12-12
2019-12-13
2019-12-14
2019-12-15
2019-12-16
2019-12-17
2019-12-18

给定:ID = 4 和 day=-5

Dates
----------  
2019-12-05
2019-12-06
2019-12-07
2019-12-08
2019-12-09

【问题讨论】:

  • recursive queryjointally 表一起使用

标签: sql-server tsql sql-server-2008-r2


【解决方案1】:

试试这个查询

FIDDLE DEMO

功能

CREATE FUNCTION udf_GetDates (@StartDate DATE, @Range INT)
RETURNS TABLE
AS
RETURN
    SELECT  
        DATEADD(DAY, nbr - 1, @StartDate) myDate
    FROM    
        (SELECT    
             ROW_NUMBER() OVER (ORDER BY c.object_id) AS Nbr
         FROM      
             sys.columns c) nbrs
    WHERE   
        nbr - 1 <= @Range

查询用法 #1:

SELECT f.myDate 
FROM udf_GetDates((SELECT dates FROM tblDates WHERE ID = 4), 2) f      

查询用法#2:

SELECT t.*, P.*
FROM tblDates t 
OUTER APPLY udf_GetDates(t.Dates, 5) p
WHERE t.ID = 4

更新答案:

下一个日期

CREATE FUNCTION udf_GetDates (@StartDate DATE, @Range INT)
RETURNS TABLE
AS
RETURN
    SELECT  
        DATEADD(DAY, nbr - 1, @StartDate) myDate
    FROM    
        (SELECT    
             ROW_NUMBER() OVER (ORDER BY c.object_id) AS Nbr
         FROM      
             sys.columns c) nbrs
    WHERE   
        nbr - 1 <= @Range

以前的日期

CREATE FUNCTION [udf_GetDates_Minuus] (@StartDate DATE, @Range INT)
RETURNS TABLE
AS
RETURN
    SELECT  
        DATEADD(DAY, -(nbr - 1), @StartDate) myDate
    FROM    
        (SELECT    
             ROW_NUMBER() OVER (ORDER BY c.object_id) AS Nbr
         FROM      
             sys.columns c) nbrs
    WHERE   
        nbr - 1 <= @Range

单个函数中的下一个和上一个日期

CREATE FUNCTION udf_GetDatesNextandPrevious(@StartDate DATE, @Range INT)
RETURNS TABLE
AS
RETURN
    SELECT  
        DATEADD(DAY, nbr - 1, @StartDate) myDate
    FROM    
        (SELECT    
             ROW_NUMBER() OVER (ORDER BY c.object_id) AS Nbr
         FROM      
             sys.columns c) nbrs
    WHERE   
        nbr - 1 <= @Range

    UNION

    SELECT  
        DATEADD(DAY, -(nbr - 1), @StartDate) myDate
    FROM    
        (SELECT    
             ROW_NUMBER() OVER (ORDER BY c.object_id) AS Nbr
         FROM      
             sys.columns c) nbrs
    WHERE   
        nbr - 1 <= @Range

Updated Fiddle

【讨论】:

  • @MAK 我这边没有错误,即使您可以在小提琴演示中检查它。执行我的功能并正确尝试
  • 这对于正数天是可以的,但是负数天呢?例如Given: ID = 4 and day= - 5
  • @MAK 我已经更新了我的答案。它会在给定日期起正负 5 天后向您发布消息。
  • @VigneshKummarA,快完成了!您能否更改该函数,以便我可以分别调用它的正负日期?
  • 如果我只想获取加号日期,那么它应该显示当前日期(即 ID = 4)和下一个日期。如果想要减去日期,那么它应该显示当前日期(即 ID = 4)和上一个日期。例如加 1:2019-12-092019-12-10,减 1:2019-12-082019-12-09
【解决方案2】:

在 sql server 中试试这段代码

DECLARE @selecteddate DATE 
DECLARE @day INT = 10 
DECLARE @id INT = 4; 
DECLARE @count INT = 0; 
DECLARE @table1 TABLE 
  ( 
     date_ DATETIME 
  ) 

SELECT @selecteddate = dates 
FROM   tbldates 
WHERE  id = @id; 

IF( @count <= @day ) 
  BEGIN 
        if(@day > 1)
        begin 
            set @day = @day - 1
        end
      WHILE @count <= @day 
        BEGIN 

            INSERT INTO @table1 
            VALUES      (Dateadd(day, @count, @selecteddate)) 

            SET @count = @count + 1 
        END 
  END 
ELSE 
  BEGIN 
      WHILE @count > @day 
        BEGIN 
            INSERT INTO @table1 
            VALUES      (Dateadd(day, @count, @selecteddate)) 

            SET @count = @count - 1 
        END 
  END 

SELECT * 
FROM   @table1 
ORDER  BY 1 

【讨论】:

    【解决方案3】:

    我尝试使用另一种格式创建函数

    create FUNCTION udf_GetDates(@MinDate DATE,@MaxDate DATE)
    RETURNS @_result table (dt date)
    AS
    begin
        insert into @_result
        SELECT  TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
                Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate)
        FROM    sys.all_objects a
                CROSS JOIN sys.all_objects b;
        return
    end
    

    然后选择这样的结果

    declare @_date date=(select Dates from tblDates where ID=4)
    select *
    from udf_GetDates(@_date,DATEADD(day,1,@_date))
    

    我得到了你想要的结果

    dt
    2019-12-09
    2019-12-10
    

    【讨论】:

      【解决方案4】:

      此 SQL 将返回两个范围之间的正确日期。只需根据您的需要进行调整即可。

          DECLARE @From               DATETIME,    
                  @To                 DATETIME
      
          SELECT  @From           =   '2019-11-13',
                  @To             =   '2019-11-19'
      
          ;WITH   Numbers         AS
      (
          SELECT  0               AS  Number
      UNION ALL
          SELECT  Number + 1      AS  Number
          FROM    Numbers
          WHERE   Number          <   DATEDIFF(d, @From, @To)
      )
          SELECT  DATEADD(d, 
                  Number, @From)  AS Date
          FROM    Numbers
      

      -- 结果

      2019-11-13 00:00:00.000
      2019-11-14 00:00:00.000
      2019-11-15 00:00:00.000
      2019-11-16 00:00:00.000
      2019-11-17 00:00:00.000
      2019-11-18 00:00:00.000
      2019-11-19 00:00:00.000
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-20
        • 1970-01-01
        • 1970-01-01
        • 2018-12-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多