账龄 - 日历和营业日不同的数据记录

Aging - Calendar and Business Days Different Records of Data

我目前正在使用 SQL Server 2012,我有一个老问题。我试图在下面包含一些示例数据和 4 条记录。

FileNumber    FileType     CompletedDate
 90440        Internal      8/11/2017
 90440        Strategy       NULL
 90441        Internal      8/10/2017
 90441        Strategy       NULL

策略的时效是从内部文件类型的完成日期一直计算到策略文件类型的完成日期。每个 FileNumber 都可以有多个与之关联的 FileType。如果策略的完成日期为 NULL,那么它将从内部文件类型的完成日期一直到今天的日期或 GETDATE()。

所以我试图显示未决策略的计数及其在工作日和日历日中的当前老化...所以基本上我希望数据像这样 return。

File Number    FileType    AgeBusiness  AgeCalendar
 90440          Strategy     2            4
 90441          Strategy     3            5

关于我将如何处理这件事的任何线索?感谢任何帮助。

这样的方法可能有效,但我不是 100% 确定,因为这取决于 table 中的文件类型,无论您是否考虑假期,当策略(或其他什么)时会发生什么最新的文件类型)完成日期的值。

;WITH Internal AS
(
    select  FileNumber, FileType,
            DATEDIFF(day,CompletedDate,getdate())- (datediff(wk, CompletedDate, getdate()) * 2) -
                case when datepart(dw, CompletedDate) = 1 then 1 else 0 end +
                case when datepart(dw, getdate()) = 1 then 1 else 0 end as AgeBusiness,
            DATEDIFF(day,CompletedDate,getdate()) as AgeCalendar
    from @test
    where FileType = 'Internal'
)
select t.FileNumber, t.FileType, i.AgeBusiness, i.AgeCalendar
from @test t
inner join Internal i on
    (t.FileNumber = i.FileNumber)
where CompletedDate is null

上面的问题是如果 Strategy(或任何最新的文件类型)有一个完成日期,它不会显示一行。因此你可能想要像

这样的东西
;WITH Internal AS
(
    select  FileNumber, FileType,
            DATEDIFF(day,CompletedDate,getdate())- (datediff(wk, CompletedDate, getdate()) * 2) -
                case when datepart(dw, CompletedDate) = 1 then 1 else 0 end +
                case when datepart(dw, getdate()) = 1 then 1 else 0 end as AgeBusiness,
            DATEDIFF(day,CompletedDate,getdate()) as AgeCalendar
    from @test
    where FileType = 'Internal'
), Latest AS
(
    select FileNumber, FileType, RANK() OVER   
        (PARTITION BY FileNumber ORDER BY COALESCE(CompletedDate,GETDATE()) DESC) AS rnk
    from @test
)
select l.FileNumber, l.FileType, i.AgeBusiness, i.AgeCalendar
from Latest l
inner join Internal i on
    (l.FileNumber = i.FileNumber)
where rnk = 1

不管它是否为空,它都会在哪里显示该行,但是以添加更密集的 RANK() 为代价。

您不需要 CTE,但我将其包括在内以使其更具可读性。

WITH DateRanges AS (
SELECT yt.FileNumber
    ,yt.FileType
    ,SELECT TOP 1 CompletedDate FROM YourTable WHERE yt.FileNumber = FileNumber AND FileType = 'Internal'  AS InternalCompletedDate
    ,CASE WHEN yt.CompletedDate IS NULL THEN CAST(GETDATE() AS DATE) ELSE yt.CompletedDate END AS StrategyCompletedDate -- I forgot the NULL part too...
FROM YourTable yt
WHERE yt.FileType = 'Strategy'
)

SELECT FileNumber
    ,FileType
    ,(DATEDIFF(dd,InternalCompletedDate, StrategyCompletedDate) + 1)
  -(DATEDIFF(wk, InternalCompletedDate, StrategyCompletedDate) * 2)
  -(CASE WHEN DATENAME(dw, InternalCompletedDate) = 'Sunday' THEN 1 ELSE 0 END)
  -(CASE WHEN DATENAME(dw, StrategyCompletedDate) = 'Saturday' THEN 1 ELSE 0 END) AS AgeBusiness    
    ,DATEDIFF(dd, InternalCompletedDate, StrategyCompletedDate) AS AgeCalendar
    FROM DateRanges

编辑:现在应该好了。我有点仓促了。