Sql 由于空,Checkintime未正确到来

Sql 由于空,Checkintime未正确到来,sql,sql-server,Sql,Sql Server,我有一个名为times的表,我正在使用mssql数据库 id | checkintime | checkouttime | ------------------------------------------------------------- 1 | 2016-06-30 07:00:00.000 | NULL | 1 | NULL |

我有一个名为times的表,我正在使用mssql数据库

id  |   checkintime             |           checkouttime    |
-------------------------------------------------------------
1   |   2016-06-30 07:00:00.000 |           NULL            |   
1   |   NULL                    |   2016-06-30 18:00:00.000 |   
1   |   2016-07-01 07:00:00.000 |           NULL            |   
1   |   NULL                    |   2016-07-01 18:00:00.000 |   
2   |   NULL                    |   2016-07-01 18:00:00.000 |
我期待着像这样的输出

id  |   checkintime     |           checkouttime    |
-----------------------------------------------------
2   |   NULL            |   2016-07-01 18:00:00.000 |   
运行此查询时:

select * from times
where checkintime is null
and CheckOutTime 
     between convert(varchar(10),getdate()-1,120) 
           and convert(varchar(10),getdate(),120)
我得到的输出如下:

id  |   checkintime     |           checkouttime    |
----------------------------------------------------
1   |   NULL            |   2016-07-01 18:00:00.000 |   
2   |   NULL            |   2016-07-01 18:00:00.000 |   
然后我把我的查询修改成这样

select * from times
where checkintime is null
and CheckOutTime 
        between convert(varchar(10),getdate()-1,120) 
               and convert(varchar(10),getdate(),120)
and not exists
(select * from times 
  where 1=1
    and ( checkintime 
              between convert(varchar(10),getdate()-1,120) 
              and convert(varchar(10),getdate(),120) 
           or CheckInTime is null
         )
)

但它给了我一个空白,我不确定这有什么错如果我理解正确,你想要的签出时间没有匹配的签入时间。您可以计算每一行的累积计数,然后获取累计签出时间大于累计签入时间的行

编辑:

SQL Server 2008不支持累积计数,但您可以:

      select t.*
      from times t outer apply
           (select count(t2.checkintime) as cnt
            from times t2
            where t2.id = t.id and
                  coalesce(t2.checkintime, t2.checkouttime) <= coalesce(t.checkintime, t.checkouttime)
           ) ins outer apply
           (select count(t2.checkouttime) as cnt
            from times t2
            where t2.id = t.id and
                  coalesce(t2.checkouttime, t2.checkintime) <= coalesce(t.checkouttime, t.checkintime)
           ) outs
where t.checkouttime is not null and outs.cnt > ins.cnt;

如果我理解正确,您希望签出时间与签入时间不匹配。您可以计算每一行的累积计数,然后获取累计签出时间大于累计签入时间的行

编辑:

SQL Server 2008不支持累积计数,但您可以:

      select t.*
      from times t outer apply
           (select count(t2.checkintime) as cnt
            from times t2
            where t2.id = t.id and
                  coalesce(t2.checkintime, t2.checkouttime) <= coalesce(t.checkintime, t.checkouttime)
           ) ins outer apply
           (select count(t2.checkouttime) as cnt
            from times t2
            where t2.id = t.id and
                  coalesce(t2.checkouttime, t2.checkintime) <= coalesce(t.checkouttime, t.checkintime)
           ) outs
where t.checkouttime is not null and outs.cnt > ins.cnt;

您能再解释一下为什么要为7/1返回id=2而不是id=1吗?不确定我是否真的理解了这些要求。bcoz id=1已经在1号签入了1 | 2016-07-01 07:00:00.000 | NULL |正如我所看到的,表达式and Not exists选择*从1=1的时间和convertvarchar10,getdate-1120和convertvarchar10,getdate之间的checkintime,120或CheckInTime为null且不存在从时间中选择*在convertvarchar10、getdate-1120和convertvarchar10、getdate、120或CheckInTime为null之间的1=1和CheckInTime对于所有行始终返回false,则您得到的为空是正确的。请检查此项。您能再解释一下为什么要返回id=2,而不是7/1的id=1吗?不确定我是否真的理解了这些要求。bcoz id=1已经在1号签入了1 | 2016-07-01 07:00:00.000 | NULL |正如我所看到的,表达式and Not exists选择*从1=1的时间和convertvarchar10,getdate-1120和convertvarchar10,getdate之间的checkintime,120或CheckInTime为null且不存在从时间中选择*在convertvarchar10、getdate-1120和convertvarchar10、getdate、120或CheckInTime为null之间的1=1和CheckInTime对于所有行始终返回false,则您得到的为空是正确的。请检查此项。它在订单附近给了我不正确的语法,我正在使用SqlSever2008。它仍然给我一个错误消息156,级别15,状态1,第6行关键字“coalesce”附近的不正确语法。Msg 156,级别15,状态1,第11行关键字“coalesce”附近的语法不正确。仍然存在错误:-Msg 4104,级别16,状态1,第6行无法绑定多部分标识符ct2.heckintime。Msg 4104,级别16,状态1,第6行无法绑定多部分标识符ct2.heckintime。Msg 4104,级别16,状态1,第11行无法绑定多部分标识符ct2.heckouttime。Msg 4104,16级,状态1,第11行无法绑定多部分标识符ct2.heckouttime。我之前也纠正了签入和checout时间,但仍然出现错误。我们可以更改代码,在代码中开始checintime和checouttime计数1天。我的意思是它应该只计算今天的结账时间和结账时间。但在我的例子中,它是从数据库中的第一个条目开始计算的,它在顺序附近给了我不正确的语法,我使用的是SqlSever2008,它仍然给了我一个错误消息156,级别15,状态1,第6行关键字“coalesce”附近不正确的语法。Msg 156,级别15,状态1,第11行关键字“coalesce”附近的语法不正确。仍然存在错误:-Msg 4104,级别16,状态1,第6行无法绑定多部分标识符ct2.heckintime。Msg 4104,级别16,状态1,第6行无法绑定多部分标识符ct2.heckintime。Msg 4104,级别16,状态1,第11行无法绑定多部分标识符ct2.heckouttime。Msg 4104,16级,状态1,第11行无法绑定多部分标识符ct2.heckouttime。我之前也纠正了签入和checout时间,但仍然出现错误。我们可以更改代码,在代码中开始checintime和checouttime计数1天。我的意思是它应该只计算今天的结账时间和结账时间。但在我的情况下,它是从DB的第一个条目开始计算的