SQL从同一领域获得日期

时间:2014-08-24 07:15:25

标签: sql vb.net visual-studio-2010 sql-server-2005

我有问题。我需要在表格中以小时数的形式获得日期差异,但问题是它保存在同一个字段中。这是我的表格。

  RecNo.    Employeeno   recorddate   recordtime    recordval
   1           001        8/22/2014      8:15 AM         1
   2           001        8/22/2014      5:00 PM         2
   3           001        8/24/2014      8:01 AM         1
   4           001        8/24/2014      5:01 PM         2

1表示时间,2表示超时。现在,我将如何获得每天工作的小时数?我想得的是这样的。

Date       hoursworked
8/22/2014       8
8/24/2014       8

我正在使用VS 2010和SQL Server 2005

3 个答案:

答案 0 :(得分:0)

你可以自我加入" in"记录相应的" out"记录并使用datediff减去它们:

SELECT     time_in.employeeno AS "Employee No",
           time_in.recorddate AS "Date",
           DATEDIFF (hour, time_in.recordtime, time_out.recordtime) 
            AS "Hours Worked"
FROM       (SELECT *
            FROM   my_table
            WHERE  recordval = 1) time_in
INNER JOIN (SELECT *
            FROM   my_table
            WHERE  recordval = 2) time_out 
           ON time_in.employeeno = time_out.employeeno AND
              time_in.recorddate = time_out.recorddate

答案 1 :(得分:0)

如果您始终记录每位员工的上班时间和超时时间,并且每天只使用一次,那么使用自我加入应该有效:

SELECT 
    t1.Employeeno, 
    t1.recorddate, 
    t1.recordtime AS [TimeIn], 
    t2.recordtime AS [TimeOut], 
    DATEDIFF(HOUR,t1.recordtime, t2.recordtime) AS [HoursWorked]
FROM Table1 t1
INNER JOIN Table1 t2 ON 
    t1.Employeeno = t2.Employeeno 
    AND t1.recorddate = t2.recorddate 
WHERE t1.recordval = 1 AND t2.recordval = 2

我将记录时间字段包括为时间,超时,如果您不希望它们只是删除它们。

请注意,此约会的计算结果为9小时,而不是您建议的8小时。

Sample SQL Fiddle

答案 2 :(得分:0)

使用此样本数据:

with table1 as (
    select * from ( values
         (1,'001', cast('20140822' as datetime),cast('08:15:00 am' as time),1)
        ,(2,'001', cast('20140822' as datetime),cast('05:00:00 pm' as time),2)

        ,(3,'001', cast('20140824' as datetime),cast('08:01:00 am' as time),1)
        ,(4,'001', cast('20140824' as datetime),cast('04:59:00 pm' as time),2)

        ,(5,'001', cast('20140825' as datetime),cast('10:01:00 pm' as time),1)
        ,(6,'001', cast('20140826' as datetime),cast('05:59:00 am' as time),2)
    )data(RecNo,EmployeeNo,recordDate,recordTime,recordVal)
)

此查询

SELECT
     Employeeno
    ,convert(char(10),recorddate,120) as DateStart
    ,convert(char(5),cast(TimeIn as time))  as TimeIn
    ,convert(char(5),cast(TimeOut as time)) as TimeOut
    ,DATEDIFF(minute,timeIn, timeOut) / 60 AS [HoursWorked]
    ,DATEDIFF(minute,timeIn, timeOut) % 60 AS [MinutesWorked]
FROM (
    SELECT 
        tIn.Employeeno, 
        tIn.recorddate, 
        dateadd(minute, datediff(minute,0,tIn.recordTime), tIn.recordDate)
             as TimeIn,             
        ( SELECT TOP 1 
             dateadd(minute, datediff(minute,0,tOut.recordTime), tOut.recordDate)
             as TimeOut
          FROM Table1 tOut
          WHERE tOut.RecordVal = 2
            AND tOut.EmployeeNo = tIn.EmployeeNo
            AND tOut.RecNo > tIn.RecNo
          ORDER BY tOut.EmployeeNo, tOut.RecNo
        ) as TimeOut
    FROM Table1 tIn
    WHERE tIn.recordval = 1
) T

产量(根据需要)

Employeeno DateStart  TimeIn TimeOut HoursWorked MinutesWorked
---------- ---------- ------ ------- ----------- -------------
001        2014-08-22 08:15  17:00   8           45
001        2014-08-24 08:01  16:59   8           58
001        2014-08-25 22:01  05:59   7           58

对于未在午夜运行的班次没有做出任何假设(见案例3)。

这个特定的实现可能不是构建这个相关子查询的最高效的方法,因此如果出现性能问题,我们可以再次查看它。但是,运行这些测试需要一个大型数据集,我现在不想构建它。