Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.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 基于结束日期和持续时间查找开始日期-T-SQL_Sql Server_Tsql_Date - Fatal编程技术网

Sql server 基于结束日期和持续时间查找开始日期-T-SQL

Sql server 基于结束日期和持续时间查找开始日期-T-SQL,sql-server,tsql,date,Sql Server,Tsql,Date,我在SQLServer中有一个表,它具有以下属性 ProjectID || Start_Date || End Date || Duration(Days) 1 10-Jan-2013 5 2 02-FEB 2013 16 3 26-Mar-2013 50 .

我在SQLServer中有一个表,它具有以下属性

ProjectID ||  Start_Date  ||   End Date    || Duration(Days)
1                             10-Jan-2013      5
2                             02-FEB 2013      16   
3                             26-Mar-2013      50  
.                                 .             .
我想根据符合条件的星期一至星期五找到开始日期。例如,结束日期:1月10日开始日期为1月4日,因为1月5日和6日为周六和周日

我想知道这在T-SQL函数、自定义T-SQL块中是如何实现的。非常感谢您的指导和帮助

这应该可以做到:

WITH tblProjects2 AS (
SELECT ProjectId, DATEADD(DAY, -Duration, EndDate) AS StartDate FROM tblProjects
)
SELECT ProjectId,
  CASE WHEN DATENAME(DW, StartDate) = 'Sunday' THEN DATEADD(day, -2, StartDate)
       WHEN DATENAME(DW, StartDate) = 'Saturday' THEN DATEADD(day, -1, StartDate)
       ELSE StartDate END AS ProperStartDate
  FROM tblProjects2
方法很简单——当你的新约会在周末时,减去1天或2天,具体取决于是周六还是周日

TBL项目的测试用例结构:

相同的测试用例数据:

INSERT INTO tblProjects VALUES (1, NULL, '10-Jan-2013', 5);
INSERT INTO tblProjects VALUES (2, NULL, '02-FEB-2013', 16);
INSERT INTO tblProjects VALUES (3, NULL, '26-Mar-2013', 50);
编辑-相同的功能,使用以下功能:

CREATE FUNCTION dbo.getStartDate(@EndDate Date, @Duration int)
RETURNS DATE
AS
BEGIN
   DECLARE @newDate DATE;
   SET @newDate = DATEADD(day, -@Duration, @EndDate);

   RETURN (CASE 
         WHEN DATENAME(DW, @newDate) = 'Sunday' THEN DATEADD(day, -2, @newDate)
         WHEN DATENAME(DW, @newDate) = 'Saturday' THEN DATEADD(day, -1, @newDate)
         ELSE @newDate END)
END;
然后您可以像这样重写上面的查询:

SELECT ProjectId, dbo.getStartDate(EndDate, Duration) AS StartDate
  FROM tblProjects
这应该做到:

WITH tblProjects2 AS (
SELECT ProjectId, DATEADD(DAY, -Duration, EndDate) AS StartDate FROM tblProjects
)
SELECT ProjectId,
  CASE WHEN DATENAME(DW, StartDate) = 'Sunday' THEN DATEADD(day, -2, StartDate)
       WHEN DATENAME(DW, StartDate) = 'Saturday' THEN DATEADD(day, -1, StartDate)
       ELSE StartDate END AS ProperStartDate
  FROM tblProjects2
方法很简单——当你的新约会在周末时,减去1天或2天,具体取决于是周六还是周日

TBL项目的测试用例结构:

相同的测试用例数据:

INSERT INTO tblProjects VALUES (1, NULL, '10-Jan-2013', 5);
INSERT INTO tblProjects VALUES (2, NULL, '02-FEB-2013', 16);
INSERT INTO tblProjects VALUES (3, NULL, '26-Mar-2013', 50);
编辑-相同的功能,使用以下功能:

CREATE FUNCTION dbo.getStartDate(@EndDate Date, @Duration int)
RETURNS DATE
AS
BEGIN
   DECLARE @newDate DATE;
   SET @newDate = DATEADD(day, -@Duration, @EndDate);

   RETURN (CASE 
         WHEN DATENAME(DW, @newDate) = 'Sunday' THEN DATEADD(day, -2, @newDate)
         WHEN DATENAME(DW, @newDate) = 'Saturday' THEN DATEADD(day, -1, @newDate)
         ELSE @newDate END)
END;
然后您可以像这样重写上面的查询:

SELECT ProjectId, dbo.getStartDate(EndDate, Duration) AS StartDate
  FROM tblProjects

读起来有点难,但速度稍微快一点

SELECT ProjectId, 
DATEADD(d, -Duration - CASE DATEDIFF(d, +Duration, EndDate) % 7 
  WHEN 5 THEN 1 
  WHEN 6 THEN 2 
  ELSE 0 END
  , EndDate)
FROM tblProjects

读起来有点难,但速度稍微快一点

SELECT ProjectId, 
DATEADD(d, -Duration - CASE DATEDIFF(d, +Duration, EndDate) % 7 
  WHEN 5 THEN 1 
  WHEN 6 THEN 2 
  ELSE 0 END
  , EndDate)
FROM tblProjects

为什么1月4日没有资格?今天是星期五,根据你的清单,应该可以。根据您的输入和预期输出,您似乎希望结束日期减去5个工作日,其中工作日为周一至周五。请澄清您想要哪一个。@Neolisk 04一月将符合条件。对不起。如果持续时间大于5天,我如何找到开始日期。为什么1月4日不符合条件?今天是星期五,根据你的清单,应该可以。根据您的输入和预期输出,您似乎希望结束日期减去5个工作日,其中工作日为周一至周五。请澄清您想要哪一个。@Neolisk 04一月将符合条件。对不起。如果持续时间大于5天,我如何才能找到开始日期。非常感谢,它工作得非常完美。你能把它写成一个T-SQL函数吗?这样我就可以输入结束日期和工作日,并将开始日期作为输出。@wali:不客气。请提供您想要的T-SQL函数的示例用法。我不太清楚你打算如何指定工作日。还有持续时间呢?如果我是你,我会把星期天和星期六的处理部分打包成一个函数,而不考虑其他的事情。因此,输入是DATE类型的单个参数,输出是表示工作日所需的向后移动1-2天的日期。在上面的示例中,您可以进行一次选择。tblProjects2作为SELECT projectd,DATEADDDAY,-Duration,EndDate作为StartDate从tblProjects Update orig_project_table set start_date=选择DATENAMEDW时的CASE,StartDate='Sunday'然后DATEADDDAY,-2,StartDate当DATENAMEDW时,StartDate='Saturday'然后DATEADDDAY,-1,StartDate ELSE StartDate END AS PROPERSTDATE从tblProjects2开始,其中tblProjects2.PROJECTD=原始项目表.PROJECTD;如果可以,请编写一个函数,执行上述查询的功能并具有以下签名。返回日期getStartDate@EndDate日期,@Duration int{}再次感谢@Neolisk。非常感谢,它工作得很好。你能把它写成一个T-SQL函数吗?这样我就可以输入结束日期和工作日,并将开始日期作为输出。@wali:不客气。请提供您想要的T-SQL函数的示例用法。我不太清楚你打算如何指定工作日。还有持续时间呢?如果我是你,我会把星期天和星期六的处理部分打包成一个函数,而不考虑其他的事情。因此,输入是DATE类型的单个参数,输出是表示工作日所需的向后移动1-2天的日期。在上面的示例中,您可以进行一次选择。tblProjects2作为SELECT projectd,DATEADDDAY,-Duration,EndDate作为StartDate从tblProjects Update orig_project_table set start_date=选择DATENAMEDW时的CASE,StartDate='Sunday'然后DATEADDDAY,-2,StartDate当DATENAMEDW时,StartDate='Saturday'然后DATEADDDAY,-1,StartDate ELSE StartDate END AS PROPERSTDATE从tblProjects2开始,其中tblProjects2.PROJECTD=原始项目表.PROJECTD;如果可以,请编写一个函数,执行上述查询的功能并具有以下签名。返回日期getStartDate@EndDate日期,@Duration int{}再次感谢@新风险。