简体   繁体   中英

How to join the next date value of the same table

I have a table in SQL with the following fields:

在此处输入图片说明

The timestamp field will have all the punches that an employee has in a day.

So having the following data:

在此处输入图片说明

I need to create 2 diferent queries.

  1. need to select all the IN timestamps with their corresponding next OUT timestamp

  2. need to select all the OUT timestamps with their corresponding previous IN timestamp

So, in the first query, I should get the following:

在此处输入图片说明

In the second query, I should get the following:

在此处输入图片说明

Any clue on how to build such queries?

HERE IS THE Fiddle : http://sqlfiddle.com/#!6/a137d/1

This looks like nice example for usage of LEAD, LAG ANALYTIC functions in SQL 2012.

SELECT * FROM
(
  SELECT EMPLOYEEID, TIMESTAMP,
  LEAD(timestamp) OVER (ORDER BY TIMESTAMP
  ) OUTTIMESTAMP, ACCESSCODE

  FROM [dbo].[employee_attendance]
  WHERE EMPLOYEEID =4 

) T 
where T.ACCESSCODE ='IN'

second query

SELECT * FROM
(
  SELECT EMPLOYEEID, TIMESTAMP,
  LAG(timestamp) OVER (ORDER BY TIMESTAMP
  ) INTIMESTAMP, ACCESSCODE

  FROM [dbo].[employee_attendance]
  WHERE EMPLOYEEID =4 

) T 
where T.ACCESSCODE ='OUT'

I believe this is what you're looking for. These queries should work on most DBMSs.

First

SELECT ea1.employeeid, ea1.timestamp AS instamp, ea2.timestamp AS outstamp
FROM employee_attendance ea1
LEFT JOIN employee_attendance ea2 
ON ea2.employeeid=ea1.employeeid 
AND ea2.accesscode = 'OUT' 
AND ea2.timestamp = (
    SELECT MIN(ea3.timestamp)
    FROM employee_attendance ea3
    WHERE ea3.timestamp > ea1.timestamp
    AND ea3.employeeid = ea1.employeeid
)
WHERE ea1.accessCode = 'IN'
AND ea1.employeeid = 4;

Second

SELECT ea1.employeeid, ea1.timestamp AS outstamp, ea2.timestamp AS instamp
FROM employee_attendance ea1
LEFT JOIN employee_attendance ea2 
ON ea2.employeeid=ea1.employeeid 
AND ea2.accesscode = 'IN' 
AND ea2.timestamp = (
    SELECT MIN(ea3.timestamp)
        FROM employee_attendance ea3
        WHERE ea3.timestamp < ea1.timestamp
        AND ea3.employeeid = ea1.employeeid
        AND ea3.timestamp > ISNULL((
            SELECT MAX(ea4.timestamp)
            FROM employee_attendance ea4
            WHERE ea4.accesscode = 'OUT'
            AND ea4.timestamp < ea1.timestamp
            AND ea4.employeeid = ea1.employeeid
        ), '2000-1-1')
)
WHERE ea1.accessCode = 'OUT'
AND ea1.employeeid = 4;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM