0

I am working on a SQL Server query to fetch the last Badge_In_Out_Time of the list of users who will be working on multiple task codes.

task_mgmt - tablename

Table Columns as follows

Task_Sn UserName Task_Code Action Badge_IN_OUT_TIME
1 Andy BLOG START 2021-07-15 08:11:45.000
2 Andy BLOG END 2021-07-15 10:11:45.000
3 Becky ACCTS START 2021-07-15 11:11:45.000
4 Chris TAX START 2021-07-15 12:11:45.000
5 Andy SOCMEDIA START 2021-07-15 12:15:45.000
6 Becky ACCTS END 2021-07-15 12:25:45.000

I am excepting the result

UserName Task_Code Badge_IN_TIME Badge_OUT_TIME
Andy BLOG 2021-07-15 08:11:45.000 2021-07-15 10:11:45.000
Becky ACCTS 2021-07-15 11:11:45.000 2021-07-15 12:25:45.000
Chris TAX 2021-07-15 12:11:45.000
Andy SOCMEDIA 2021-07-15 12:15:45.000

I really couldn't come up with any query for this. I am a beginner in SQL and I know CRUD operations. This seems to be super complex for me.

Select UserName, Task_Code, Badge_In_Time, Badge_Out_Time from task_mgmt order by Badge_IN_OUT_TIME desc 
1
  • I really couldn't come up with any query for this. I am a beginner in SQL and i know CRUD operations. This seems to be super complex for me. Commented Jul 15, 2021 at 21:47

2 Answers 2

1

Just do a simple pivot by aggregating your rows to the desired level (UserName,TaskCode) and then pivoting using MAX or MIN(CASE WHEN .... END)

Like so:

SELECT tm.UserName ,tm.Task_Code ,MIN(CASE WHEN tm.Action = 'START' THEN tm.Badge_IN_OUT_TIME ELSE NULL END) AS Badge_IN_TIME ,MAX(CASE WHEN tm.Action = 'END' THEN tm.Badge_IN_OUT_TIME ELSE NULL END) AS Badge_OUT_TIME FROM task_mgmt AS tm GROUP BY tm.UserName ,tm.Task_Code 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. I will try this solution and let you know. Really appreicated.
1

This is a type of gaps-and-islands problem, the islands are pairs of START and END.

There are a number of solutions. Here, I have assumed that START always defines the beginning of each group, and there may or may not be an END.

We can calculate a grouping number for each island by using a windowed COUNT, partitioning by UserName and Task_Code. We then simply group up also by the new grouping number, and pivot the timestamp.

SELECT t.UserName, t.Task_Code MIN(CASE WHEN t.Action = 'START' THEN t.Badge_IN_OUT_TIME END) Badge_IN_TIME, MAX(CASE WHEN t.Action = 'END' THEN t.Badge_IN_OUT_TIME END) Badge_OUT_TIME FROM ( SELECT *, COUNT(CASE WHEN t.Action = 'START' THEN 1 END) OVER (PARTITION BY t.UserName, t.Task_Code ORDER BY t.Badge_IN_OUT_TIME ROWS UNBOUNDED PRECEDING) grp FROM task_mgmt t ) t GROUP BY t.UserName, t.Task_Code t.grp; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.