如何检查设置的行是否覆盖整个时间范围

时间:2016-06-25 11:06:14

标签: sql sql-server sql-server-2008 sql-timestamp

我有一个表,其中有两列StartTime和EndTime。值填写为:

 declare @tbl Table(
colA VARCHAR(50),
colS VARCHAR(50),
DATES DATE,
STARTTIME TIME,
ENDTIME TIME,
ID BIGINT NOT NULL IDENTITY(1,1)
)

INSERT INTO @tbl
SELECT 'A','S',convert(date,'2015-09-21'),convert(TIME,'12:45'),convert(TIME,'13:30')
UNION ALL
SELECT 'A','S',convert(date,'2015-09-21'),convert(TIME,'13:15'),convert(TIME,'13:45')
UNION ALL
SELECT 'A','S',convert(date,'2015-09-21'),convert(TIME,'13:30'),convert(TIME,'16:50')
UNION ALL
SELECT 'A','S',convert(date,'2015-09-21'),convert(TIME,'13:15'),convert(TIME,'13:50')

因此,我想检查此表的所有行中的StartTime和EndTime是否涵盖此表的Minimum StartTime和Maximum EndTime之间的整个时间段。 因此,从这些行中可以清楚地看出它是真的。但是对于下面的一组行,由于它们之间的时间间隔,它不会是真的。所以我只想得到真或假。

INSERT INTO @tbl
SELECT 'A','S',convert(date,'2015-09-21'),convert(TIME,'08:45'),convert(TIME,'09:15')
UNION ALL
SELECT 'A','S',convert(date,'2015-09-21'),convert(TIME,'11:10'),convert(TIME,'11:25')

我已设法完成所有其他任务,这是他们的最终结果。这是最后的任务,我完全不知道如何去做。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:2)

通常间隔可以是任意长度,因此比较相邻行远非完全解决方案。除了上面引用的Itzik Ben-Gan's Packing Intervals解决方案之外,另一个完整的解决方案是检查每一分钟(或其他粒度)。

select uncoverdMinutes=count(*) -- 0 is true
from(
    select colA, colS, t.m
    from ( 
        select colA, colS
          , mst = min(starttime)
          , cnt = datediff(minute, min(starttime), max(endtime)) + 1
        from @tbl
        group by colA, colS 
    ) prm 
    cross apply (
        select top(prm.cnt)
            m = dateadd(minute
                      ,row_number() over(order by (select null)) - 1
                      ,prm.mst)                                    
        from sys.all_objects -- use tally table instead, if you have one
        ) t
  ) mi
where not exists (
    select 1 
    from @tbl t
    where mi.m between t.starttime and t.endtime)

答案 1 :(得分:1)

尝试

;with a as (select *,row_number() over (order by DATES,starttime) rn from @tbl)

select a.*,
case when isnull(b.endtime,a.endtime)>=a.STARTTIME then 'true' else 'false' end 
 from a left join a b on a.rn=b.rn+1

答案 2 :(得分:1)

如果有足够的时间来检查下一行的时间间隔是否与下一行间隔相交,那么OUTER APPLY应该为你做的事情:

colA    colS    DATES       STARTTIME           ENDTIME             ID  Seq
A       S       2015-09-21  08:45:00.0000000    09:15:00.0000000    5   FALSE
A       S       2015-09-21  11:10:00.0000000    11:25:00.0000000    6   FALSE
A       S       2015-09-21  12:45:00.0000000    13:30:00.0000000    1   TRUE
A       S       2015-09-21  13:15:00.0000000    13:45:00.0000000    2   TRUE
A       S       2015-09-21  13:15:00.0000000    13:50:00.0000000    4   TRUE
A       S       2015-09-21  13:30:00.0000000    16:50:00.0000000    3   TRUE

给定数据的输出:

 x^2/rx^2 + y^2/ry^2 = 1

答案 3 :(得分:1)

- 最后一列的第一个示例数据为1,第二列为0。

    public static class UnityBootstrap
{
    private static IUnityContainer container;
    public static IUnityContainer Container
    {
        get
        {
            if (container == null)
                InitializeContainer();
            return container;
        }
    }

    public static void InitializeContainer()
    {
        container = new UnityContainer();
        container.RegisterType<ICustBillingTypeService, CustBillingTypeService>();
        container.RegisterType<IDataContext, DataContext>();
        container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
    }
}

    public interface IRepository<T> where T : class, IObjectState
{
    T FindOne(Expression<Func<T, bool>> predicate);
}

    public class Repository<T> : IRepository<T> where T : class, IObjectState
{
    private readonly IDataContext context;
    private readonly IDbSet<T> dbSet;

    public Repository() { }

    public Repository(IDataContext ctx)
    {
        this.context = ctx;
        var dbContext = context as DbContext;
        dbSet = dbContext.Set<T>();
    }

    public virtual T FindOne(Expression<Func<T, bool>> predicate)
    {
        return dbSet.SingleOrDefault(predicate);
    }
}

public interface ICustBillingTypeService
{
    CustBillingType GetCustBillingTypeByPKId(int pkId);
}

public class CustBillingTypeService : ICustBillingTypeService
{
    IRepository<CustBillingType> custBillingTypeRepo;

    public CustBillingTypeService() { }

    public CustBillingTypeService(IRepository<CustBillingType> repo)
    {
        custBillingTypeRepo = repo;
    }
    public CustBillingType GetCustBillingTypeByPKId(int pkId)
    {
        var cbt = custBillingTypeRepo.FindOne(x => x.PKId == pkId);
        return cbt;
    }
}

public interface IDataContext : IDisposable
{
    int SaveChanges();
    void SyncObjectState<TEntity>(TEntity entity) where TEntity : class, IObjectState;
    void SyncObjectsStatePostCommit();
}


public class DataContext : DbContext, IDataContext
{
    private readonly Guid _instanceId;
    bool _disposed;

    public DataContext(string nameOrConnectionString) : base(nameOrConnectionString)
    {
        _instanceId = Guid.NewGuid();
        Configuration.LazyLoadingEnabled = false;
        Configuration.ProxyCreationEnabled = false;
    }
    public Guid InstanceId { get { return _instanceId; } }
    public override int SaveChanges()
    {
        SyncObjectsStatePreCommit();
        var changes = base.SaveChanges();
        SyncObjectsStatePostCommit();
        return changes;
    }

    protected override void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
            }
            _disposed = true;
        }

        base.Dispose(disposing);
    }
}

public partial class TestModel : DataContext
{
    public TestModel() : base("name=TestModel") {}

    public virtual DbSet<CustBillingType> CustBillingTypes { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        CustBillingTypeModelBuilder.Map(modelBuilder);
    }
}

[TestClass]
public class UnityTestCases
{
    private IUnityContainer uContainer;
    private ICustBillingTypeService icbService;
    public UnityTestCases()
    {
        uContainer = UnityBootstrap.Container;
        icbService = uContainer.Resolve<ICustBillingTypeService>();
    }
    [TestMethod]
    public void GetCustBillingTypeByPKId_return_ValidObj()
    {
        var obj = icbService.GetCustBillingTypeByPKId(pkId: 15);
        Assert.IsNotNull(obj);
    }
}
相关问题