Sql 根据可能重叠的范围获取最极端变量的天数

Sql 根据可能重叠的范围获取最极端变量的天数,sql,sql-server,Sql,Sql Server,我有一个数据库,里面有手动输入的记录。在数据库中,有两个已输入的字段“开始日期”和“结束日期”。在输入这些日期的同时,用户还输入了优先级。我需要能够提取包括所有天数在内的天数范围,作为最高优先级的数字,并将日期范围与最后一批列中的所有日期相对应 以下是数据库中的一条记录: OurID TotalCalculatedKnownDays Priority KnownStartDate KnownEndDate CategoryCode E

我有一个数据库,里面有手动输入的记录。在数据库中,有两个已输入的字段“开始日期”和“结束日期”。在输入这些日期的同时,用户还输入了优先级。我需要能够提取包括所有天数在内的天数范围,作为最高优先级的数字,并将日期范围与最后一批列中的所有日期相对应

以下是数据库中的一条记录:

OurID   TotalCalculatedKnownDays    Priority    KnownStartDate          KnownEndDate            CategoryCode    ExternalID  InputtedStartDate       InputtedEndDate         InputeedCalulatedDays   Month
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1234    5                           3           2013-11-20 18:04:00.000 2013-11-24 23:20:00.000 XX1             5678        2013-11-20 00:00:00.000 2013-11-24 00:00:00.000 5                       Nov-13
1234    5                           4           2013-11-20 18:04:00.000 2013-11-24 23:20:00.000 XX1             5678        2013-11-24 00:00:00.000 2013-11-24 00:00:00.000 1                       Nov-13
1234    5                           4           2013-11-20 18:04:00.000 2013-11-24 23:20:00.000 XX1             5678        2013-11-24 00:00:00.000 2013-11-25 11:00:00.000 2                       Nov-13
1235    3                           2           2013-11-07 10:45:00.000 2013-11-09 23:45:00.000 XX2             5640        2013-11-07 00:00:00.000 2013-11-08 00:00:00.000 2                       Nov-13
1235    3                           3           2013-11-07 10:45:00.000 2013-11-09 23:45:00.000 XX2             5640        2013-11-08 00:00:00.000 2013-11-09 00:00:00.000 2                       Nov-13
1235    3                           4           2013-11-07 10:45:00.000 2013-11-09 23:45:00.000 XX2             5640        2013-11-09 00:00:00.000 2013-11-09 00:00:00.000 1                       Nov-13
我需要的是,输出一个更正的列表,如下所示:

OurID   TotalCalculatedKnownDays    Priority    KnownStartDate          KnownEndDate            CategoryCode    ExternalID  InputtedStartDate       InputtedEndDate         InputeedCalulatedDays   Month
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1234    5                           3           2013-11-20 18:04:00.000 2013-11-24 23:20:00.000 XX1             5678        2013-11-20 00:00:00.000 2013-11-23 00:00:00.000 4                       Nov-13
1234    5                           4           2013-11-20 18:04:00.000 2013-11-24 23:20:00.000 XX1             5678        2013-11-24 00:00:00.000 2013-11-24 00:00:00.000 1                       Nov-13
1234    5                           4           2013-11-20 18:04:00.000 2013-11-24 23:20:00.000 XX1             5678        2013-11-25 00:00:00.000 2013-11-25 11:00:00.000 1                       Nov-13
1235    3                           2           2013-11-07 10:45:00.000 2013-11-09 23:45:00.000 XX2             5640        2013-11-07 00:00:00.000 2013-11-07 00:00:00.000 1                       Nov-13
1235    3                           3           2013-11-07 10:45:00.000 2013-11-09 23:45:00.000 XX2             5640        2013-11-08 00:00:00.000 2013-11-08 00:00:00.000 1                       Nov-13
1235    3                           4           2013-11-07 10:45:00.000 2013-11-09 23:45:00.000 XX2             5640        2013-11-09 00:00:00.000 2013-11-09 00:00:00.000 1                       Nov-13
我已经能够获得每个ID的唯一日期列表,如果详细信息按天分类也没关系,尽管最好不是有一种方法可以这样做,但我无法确定如何根据OurID分配当天记录的最高优先级。以下是我对此的看法:

DECLARE @t TABLE
(
    OurID VARCHAR(10),
    TotalCalculatedKnownDays INT,
    Priority VARCHAR(50),
    KnownStartDate datetime,
    KnownEndDate datetime,
    CategoryCode varchar(10),
    ExternalID varchar(10),
    InputtedStartDate datetime,
    InputtedEndDate datetime,
    [Days] int,
    [Month] varchar(10)
);

insert into @t
select p. OurID, DATEDIFF(DAY, i. KnownStartDate, i. KnownEndDate) + 1 AS TotalCalculatedKnownDays, p. Priority, i. KnownStartDate, i. KnownEndDate, i. CategoryCode, p. ExternalID, CONVERT(DATETIME, p. InputtedStartDate, 120) as 'InputtedStartDate', CONVERT(DATETIME, ISNULL(p. InputtedEndDate1, DATEADD(dd, 1, p. InputtedEndDate2)), 120) as 'InputtedEndDate', DATEDIFF(DAY, p. InputtedStartDate, ISNULL(p. InputtedEndDate1, DATEADD(dd, 1, p. InputtedEndDate2))) + 1 AS 'Days', CONVERT(CHAR(3), i.KnownEndDate, 100) + '-' + CONVERT(CHAR(2), i. KnownEndDate, 12) as 'Month'
from openquery(ls1,'XXXXX') p
INNER JOIN [tbl2] i ON i. ExternalID = p. ExternalID and i.OurID = p.OurID
;

with [range](d,s) as
(
    SELECT DATEDIFF(DAY, MIN InputtedStartDate), MAX InputtedEndDate))+1,
    MIN(InputtedStartDate)
    FROM @t
),
n(d) AS
(
    SELECT DATEADD(DAY, n-1, (SELECT MIN(s) FROM [range]))
    FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id])
    FROM sys.all_objects) AS s(n)
    WHERE n <= (SELECT MAX(d) FROM [range])
)
select tRef.* from (
SELECT distinct t.OurID, n.d
FROM n CROSS JOIN @t AS t
WHERE n.d BETWEEN t InputtedStartDate AND t InputtedEndDate) tRef
order by 1, 2;

我开发了一个基于每一天的解决方案。这并不是最好的解决方案,但它每天都能发挥作用,而且是最高优先级的。如果仍能找到第一个解决方案,那就太好了,但现在这样就可以了

DECLARE @t TABLE
(
    OurID VARCHAR(10),
    TotalCalculatedKnownDays INT,
    Priority VARCHAR(50),
    KnownStartDate datetime,
    KnownEndDate datetime,
    CategoryCode varchar(10),
    ExternalID varchar(10),
    InputtedStartDate datetime,
    InputtedEndDate datetime,
    [Days] int,
    [Month] varchar(10)
);

insert into @t
select p. OurID, DATEDIFF(DAY, i. KnownStartDate, i. KnownEndDate) + 1 AS TotalCalculatedKnownDays, p. Priority, i. KnownStartDate, i. KnownEndDate, i. CategoryCode, p. ExternalID, CONVERT(DATETIME, p. InputtedStartDate, 120) as 'InputtedStartDate', CONVERT(DATETIME, ISNULL(p. InputtedEndDate1, DATEADD(dd, 1, p. InputtedEndDate2)), 120) as 'InputtedEndDate', DATEDIFF(DAY, p. InputtedStartDate, ISNULL(p. InputtedEndDate1, DATEADD(dd, 1, p. InputtedEndDate2))) + 1 AS 'Days', CONVERT(CHAR(3), i.KnownEndDate, 100) + '-' + CONVERT(CHAR(2), i. KnownEndDate, 12) as 'Month'
from openquery(ls1,'XXXXX') p
INNER JOIN [tbl2] i ON i. ExternalID = p. ExternalID and i.OurID = p.OurID
;

with [range](d,s) as
(
    SELECT DATEDIFF(DAY, MIN InputtedStartDate), MAX InputtedEndDate))+1,
    MIN(InputtedStartDate)
    FROM @t
),
n(d) AS
(
    SELECT DATEADD(DAY, n-1, (SELECT MIN(s) FROM [range]))
    FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id])
    FROM sys.all_objects) AS s(n)
    WHERE n <= (SELECT MAX(d) FROM [range])
)
select tRef.* from (
select orig.OurID, MAX(orig.TotalCalculatedKnownDays) AS 'TotalCalculatedKnownDays', MAX(orig.Priority) as 'Priority', MIN(KnownStartDate) as 'KnownStartDate', MAX(KnownEndDate) as 'KnownEndDate', MAX(orig.CategoryCode) as 'CategoryCode', MAX(orig.ExternalID) as 'ExternalID', tRef.d as 'Chargeable Date', MAX(orig.month) as 'Month' from (
SELECT distinct t.OurID, n.d
FROM n CROSS JOIN @t AS t
WHERE n.d BETWEEN t.InputtedStartDate AND t.InputtedEndDate) tRef
LEFT JOIN @t as orig ON tRef.OurID = orig.OurID AND tRef.d BETWEEN orig.InputtedStartDate AND orig.InputtedEndDate
GROUP BY orig.OurID, tRef.d
order by 1, 8;

是否要正确计算列InputedCalulatedDays?这只是问题的一半。另一半是日期需要编辑。基于优先级,最高优先级优先于较低优先级。更正后的输出显示了SQL语句返回的最佳结果。那么订单1234的最后一条记录的2013-11-25 11:00:00.000结束日期来自何处?这是一个输入错误的记录示例。在原始表格中输入的开始日期为24日,结束日期为25日。在固定版本中,即使这是错误的,因为日期在已知的结束日期之后,它应该显示出来,尽管它可以[嗯,应该]与上面的记录合并,因为它具有相同的优先级代码,但我很快就完成了该示例,没有注意到该错误。如您所见,尽管我们预计5天,但由于错误,该记录应为6天。