老龄化 - 日历和工作日不同的数据记录

时间:2017-08-14 15:35:35

标签: sql sql-server-2012 calendar case date-difference

我目前正在使用SQL Server 2012而且我有一个老化的问题。我尝试将下面的一些样本数据包含在4条记录中。

   {
        "key": "ctrl+enter",
          "command": "workbench.action.terminal.runSelectedText",
            "when": "editorTextFocus && editorHasSelection"
    }
    {
        "key": "ctrl+enter",
          "command": "macros.execCurLn",
            "when": "editorTextFocus && !editorHasSelection"
    },
{ "key": "ctrl+`", "command": "workbench.action.terminal.focus"},
{ "key": "ctrl+`", "command": "workbench.action.focusActiveEditorGroup", "when": "terminalFocus"}

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

所以我试图在商业和日历日显示未完成策略的数量及其当前的老化...所以基本上我希望数据像这样返回。

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

关于我如何解决这个问题的任何线索?任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:2)

这样的事情可能有用,但我不能100%肯定,因为它取决于表格中的文件类型,是否考虑假期,策略时会发生什么(或者是最新的文件类型) )具有完成日期的值。

;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

上述问题是,如果策略(或任何最新的文件类型)已完成日期,它将不会显示一行。因此,您可能需要类似

的内容
;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()。

答案 1 :(得分:1)

您不需要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

编辑:现在应该很好。我冲了一下。