【问题标题】:Merge Date Ranges Linq to SQL合并日期范围 Linq 到 SQL
【发布时间】:2016-04-26 01:48:02
【问题描述】:

注意:这是一个 linq to sql 问题,而不是一般的 linq 问题。 Linq to SQL 对您可以执行的操作有限制。

我需要合并日期范围以消除重叠。在 stackoverflow 上已经有这个问题的答案,但是答案不能在 linq to sql 中实现(没有递归 CTE、滞后等)。

SQL: Merge Date Ranges

使用 SQL 92 语法的第二个答案有一个错误(如果存在与相同结束日期相交的行,则这些行不被视为重叠)。

有什么建议吗?

提前谢谢

样本数据(无耻地从另一个 stackover 流 Q 复制)

PK |开始日期 |结束日期


1 | 2012/07/21 02:00 | 2012/07/21 04:00
2 | 2012/07/21 03:00 | 2012/07/21 10:00
3 | 2012/07/21 06:00 | 2012/07/21 17:00
4 | 2012/07/21 18:00 | 2012/07/21 19:00

合并将导致:

PK |开始日期 |结束日期


1 | 2012/07/21 02:00 | 2012/07/21 17:00
2 | 2012/07/21 18:00 | 2012/07/21 19:00

【问题讨论】:

  • 你能用一些样本数据/想要的结果来填写这个问题吗?
  • 如果您不想要sql 的答案,最好删除该标签。
  • 这个问题是特定于 linq-to-sql 的,因此不是一个通用的 linq 问题 - 不是这些@gnalck 的重复

标签: c# linq date linq-to-sql


【解决方案1】:

让我们先创建一个运动场:

CREATE TABLE [dbo].[dateTable](
    [dt_from] [datetime2](7) NOT NULL,
    [dt_to] [datetime2](7) NOT NULL
) ON [PRIMARY]
GO

INSERT INTO [dbo].[dateTable]
           ([dt_from]
           ,[dt_to])
     VALUES 
('2012-07-21 02:00:00', '2012-07-21 04:00:00'),
('2012-07-21 03:00:00', '2012-07-21 10:00:00'),
('2012-07-21 06:00:00', '2012-07-21 17:00:00'),
('2012-07-21 18:00:00', '2012-07-21 19:00:00')
GO

我们有一堆间隔,我们想合并它们。我们需要找到这些合并区间的开始和结束。合并的开始必须满足这些约束:

  1. 这是某个未合并区间的开始。
  2. 没有这样的时间间隔,它在这个时间或更晚结束并且比这个时间更早开始。
  3. 如果多个间隔同时开始,我们只使用一次。

合并端是相似的。每个合并的开始都只有一个合并的结束。唯一的问题可能是未合并的间隔,其中开始大于结束。我决定将它们视为无效而跳过。代码在这里

var ed = new DataClasses1DataContext();

var res = ed.dateTables
    .Where(d => d.dt_from <= d.dt_to) //change to < for nonzero intervals only
    .Select(f => f.dt_from)
    .Distinct()
    .Where(w => !ed.dateTables.Any(a => a.dt_from < w && a.dt_to >= w))                
    .Select(date => new
    {
        FROM = date,
        TO = ed.dateTables.Select(t => t.dt_to)
        .Where(w => !ed.dateTables.Any(a => a.dt_from <= w && a.dt_to > w) && w >= date)
        .Min()
    }).ToArray();

foreach (var r in res)
{
    Console.WriteLine("FROM: " + r.FROM + " TO: " + r.TO);
}

这里是结果:

FROM: 21.07.2012 2:00:00 TO: 21.07.2012 17:00:00 
FROM: 21.07.2012 18:00:00 TO: 21.07.2012 19:00:00

生成的SQL并不奇怪,就是有点乱

SELECT [t1].[dt_from] AS [FROM], (
    SELECT MIN([t3].[dt_to])
    FROM [dbo].[dateTable] AS [t3]
    WHERE (NOT (EXISTS(
        SELECT NULL AS [EMPTY]
        FROM [dbo].[dateTable] AS [t4]
        WHERE ([t4].[dt_from] <= [t3].[dt_to]) AND ([t4].[dt_to] > [t3].[dt_to])
        ))) AND ([t3].[dt_to] >= [t1].[dt_from])
    ) AS [TO]
FROM (
    SELECT DISTINCT [t0].[dt_from]
    FROM [dbo].[dateTable] AS [t0]
    WHERE [t0].[dt_from] <= [t0].[dt_to]
    ) AS [t1]
WHERE NOT (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[dateTable] AS [t2]
    WHERE ([t2].[dt_from] < [t1].[dt_from]) AND ([t2].[dt_to] >= [t1].[dt_from])
    ))

【讨论】:

  • 非常感谢。完美运行
猜你喜欢
  • 2014-10-13
  • 1970-01-01
  • 2018-09-02
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
  • 2015-03-15
  • 2021-06-09
  • 1970-01-01
相关资源
最近更新 更多