SQL Server查询输入和输出

问题描述 投票:0回答:2

这是我保存在MS SQL数据库中的DTR设备

ID | Employee_ID | Date | InOutMode -------+-------------+---------------------+----------- 70821 | 104 | 2019-10-11 19:00:00 | 0 70850 | 104 | 2019-10-12 07:01:00 | 1

如果我要分离输入和输出,它应该像这样:

ID | Employee_ID | IN | OUT -------+-------------+---------------------+----------- 70821 | 104 | 2019-10-11 19:00:00 | 2019-10-12 07:01:00

发生的情况是,我不知道我的查询是否有错。超时不是2019-10-12而是2019-10-11与TIME-IN一样,它看起来像这样:

ID | Employee_ID | IN | OUT -------+-------------+---------------------+----------- 70821 | 104 | 2019-10-11 19:00:00 | 2019-10-11 07:01:00

sql sql-server
2个回答
0
投票

尝试一下,

DECLARE @Temp_Table Table
(
    Empoyee_id int,
    [Date] datetime,
    [InOutMode] bit
)

INSERT INTO @Temp_Table
(
    Empoyee_id,[Date],[InOutMode]

)
SELECT 104,'20191011 09:30',1 
UNION ALL
SELECT 104,'20191011 19:30',0 
UNION ALL
SELECT 104,'20191012 09:30',1 
UNION ALL
SELECT 104,'20191012 12:30',0 
UNION ALL
SELECT 104,'20191012 19:00',0 
UNION ALL
SELECT 104,'20191013 09:30',1 
UNION ALL
SELECT 104,'20191013 07:30',0
UNION ALL
SELECT 104,'20191014 09:30',1 

SELECT Empoyee_id,[Date],[In],IIF([In]>[Out],null,[Out]) as [Out]
FROM
(
    SELECT Empoyee_id,CAST([Date] AS DATE) AS [Date],
    MIN(IIF(InOutMode=1,[Date],NULL)) AS [In] ,
    MAX(IIF(InOutMode=0,[Date],NULL)) AS [Out]
    FROM @Temp_Table
    GROUP BY Empoyee_id,CAST([Date] AS DATE)
)A

0
投票

尝试一下:

;
WITH Ins as (
  Select *
  FROM   HR_DTR_Device 
  WHERE  InOutMode = 0
),
Outs as (
  Select *
  FROM   HR_DTR_Device
  WHERE  InOutMode = 1
)
SELECT Ins.ID,
       Ins.Employee_ID,
       Ins.Date as [In]
       (
         SELECT Min(Outs.Date)
         FROM   Outs
         WHERE  Ins.Employee_ID = Outs.Employee_ID
            AND Outs.Date > Ins.Date
       ) as [Out]
FROM   Ins
WHERE  Ins.Employee_ID = '104'

这是什么:

  1. InsOuts分开,就好像它们是分开的数据源一样。实际上,使用Common Table Expressions可以预定义子查询并为其命名。
  2. 对于Ins中的每个记录,从Outs中查找仍大于In日期的最小日期。 (这假设您的记录是完整的,并且您永远不可能连续有两个Ins,因为有人忘记了退出。)
  3. Out日期何时发生没有任何假设,只是它比In日期晚(根据定义)。这样,您不必担心员工是在当天晚些时候还是第二天早些时候离开(如果您有不同工作班次的员工。)
  4. 还将显示员工已签到但尚未签出的所有条目。

我认为您的大错误在这里:

 (SELECT MAX(Date) FROM HR_DTR_Device XX 
 WHERE InOutMode = 1
   AND XX.Employee_ID = AA.Employee_ID
   AND CAST(XX.Date AS DATE) = CAST(AA.Date AS DATE)) AS 'Out'

您将返回该雇员在同一日历日期(并且是Out)的最大日期。但是,如果员工工作到第二天早上,则日期将已更改!

您可以通过将测试更改为此来解决此问题:

CAST(DATEADD(d, -1, XX.Date) AS DATE) = CAST(AA.Date AS DATE)

...但是它仅适用于通宵工作的员工,而我的解决方案只是查找员工上班后下一次下班的时间,而不管是在同一天,第二天还是下一周!

如果您喜欢此解决方案,请将其标记为您接受的解决方案。谢谢。


-1
投票

这是我保存在MS SQL数据库中的DTR设备

© www.soinside.com 2019 - 2024. All rights reserved.