单列中日期范围的存储过程

时间:2013-12-13 06:07:20

标签: c# asp.net sql-server

在我的项目中找到问题的解决方案

我有与合同相关的阶段。也就是说,合同可以处于Active阶段,Process阶段或Terminated阶段。

我需要得到合同在每个阶段的日子。

例如,如果合同C1位于从Active20/10/2013的{​​{1}}阶段,那么22/10/2013阶段Process22/10/2013,最后在25/10/2013阶段,从Terminated25/10/2013然后再从26/10/2013再从Active26/10/2013,然后我应该得到结果

  • 有效= 4天
  • 处理= 3天
  • 已终止= 1天/同样

我的表格是使用以下列创建的:

  • 28/10/2013(主键)
  • EntryIdStageId表的外键)
  • StageContractId表的外键)
  • contract

如何在SQL Server中执行此操作?


正如要求的那样找到表格条目:

EntryID |舞台ID |合同ID | DateChange

1 | A1 | C1 | 20/10/2013

2 | P1 | C1 | 22/10/2013

3 | T1 | C1 | 25/10/2013

4 | A1 | C1 | 26/10/2013

5 | P1 | C1 | 28/10/2013

6 | T1 | C1 | Null(目前处于此阶段)


需要在舞台ID上使用group by

3 个答案:

答案 0 :(得分:2)

检查并确保如何在表格中填充数据非常重要。仅基于您的示例数据,并注意如果您的entryid不是按顺序排列,那么您可以使用row_number创建一个序列。

declare @t table(EntryId int identity(1,1), StageId int,ContractId varchar(10),DateofStageChange date)
insert into @t values 
(1,'C1','2013-10-20'),(1,'C1','2013-10-22'),(2,'C1','2013-10-22'),(2,'C1','2013-10-25')
,(3,'C1','2013-10-25'),(3,'C1','2013-10-26'),(1,'C1','2013-10-26'),(1,'C1','2013-10-28') 

Select StageId,sum([noOfDays]) [totalNofDays] from 
(select a.StageId,a.ContractId,a.DateofStageChange [Fromdate],b.DateofStageChange [ToDate]  
,datediff(day,a.DateofStageChange,b.DateofStageChange) [noOfDays]
from @t a
inner join @t b on a.StageId=b.StageId and b.EntryId-a.EntryId=1)t4
group by StageId

答案 1 :(得分:1)

您不能使用当前的结构。

您可以通过datediff(d, getdate(), DateOfStageChange)

获取最新版本

但您没有任何历史记录,因此您无法获得以前的状态

答案 2 :(得分:0)

这可以在带有CTE的SQL中完成。

您没有提供您的桌面名称,因此您需要更改我在下面指出的位置,但它看起来像这样:

;WITH cte
AS (
SELECT 
    DateofStageChange, StageID, ContractID,
    ROW_NUMBER() OVER (ORDER BY ContractID, StageId, DateofStageChange) AS RowNum
FROM 
    DateOfStageChangeTable  //<==== Change this table name
)

SELECT 
   a.ContractId,
   a.StageId, 
   Coalesce(sum(DATEDIFF(d ,b.DateofStageChange,a.DateofStageChange)), 'CurrentState`) as Days
FROM 
 cte AS A
LEFT OUTER JOIN
 cte AS B   
 ON A.RowNum = B.RowNum + 1 and a.StageId = b.StageId and a.ContractId = b.ContractId
group by a.StageId, a.ContractId

这实际上只是一个在表上创建行号的自联接,通过StageID和日期对表进行排序,然后加入自身。阶段id和日期的第一行上的第一个日期,连接到第二行的第二个日期,然后以天为单位计算日期范围。

这假设每个阶段只有2个日期,如果你有几个,你只需要在cte表上做一个min和max。

编辑:

根据您的示例数据,上述查询应该可以正常运行。如果您遇到任何语法错误,请告诉我,我会修复它们。

我添加了一个合并来表明他们目前所处的状态。