由于NULL,Checkintime无法正确显示

时间:2016-07-02 01:36:44

标签: sql sql-server

我有一个名为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
         )
)

但它让我空白,我不确定这个

有什么问题

1 个答案:

答案 0 :(得分:2)

如果我理解正确,您希望checkouttime次没有匹配的checkintime。您可以计算每个累积计数,然后选择checkouttime的累计数大于checkintime累积数的行。

select t.*
from (select t.*,
             count(checkintime) over (partition by id order by coalesce(checkintime, checkouttime)) as cnt_in,
             count(checkouttime) over (partition by id order by coalesce(checkouttime, checkintime)) as cnt_out
      from times t
     ) t
where checkouttime is not null and cnt_out > cnt_in;

编辑:

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;