Home > Software engineering >  SQL Query for applying a column value based on the Min and Max
SQL Query for applying a column value based on the Min and Max

Time:07-11

I would like to ask for help on how to assign a value to a column base on the maximum and minimum.

My sample table

1

My query

SELECT 
    a.id,
    a.terminal_id,
    a.emp_code,
    DATEADD(dd, 0, DATEDIFF(dd, 0, a.punch_time)) AS TranDate,
    a.punch_time,
    a.punch_time,
    a.punch_state,
    a.area_alias
FROM iclock_transaction a 
WHERE a.emp_code = '8734'  
      AND datediff(day,a.punch_time,'06/07/2022') = 0
GROUP BY
    a.id,
    a.terminal_id,
    a.emp_code,
    a.punch_time,
    a.punch_state,
    a.area_alias

What I want to achieve is to add a status e.g. 2

CodePudding user response:

You know you need to refer to the min and max values on a date basis to accomplish this. I expect to see that attempt in your code. You can use MIN and MAX as simple aggregates (old way) or as analytical functions (newer way).

The old way uses a traditional aggregation in a CTE (or derived table) and simply joins the rows of the table to the CTE. That allows you to compare the punch value with the min and max to know if the row represents the first "in" or the last "out". I took some liberties with that logic and made assumptions. Do you see them? Are they appropriate? Can someone leave without an "out" row? Know your data!

with minmax as (
   select emp_code, trandate, 
      min(punch_time) as first_in, 
      max(punch_time) as last_out
   from @x 
   group by emp_code, trandate 
)
select clocktran.*, minmax.first_in, minmax.last_out, 
       case when clocktran.punch_time = minmax.first_in then 'Time In'
       when clocktran.punch_time = minmax.last_out then 'Time Out'
       when clocktran.punch_state = 1 then 'Break out'
       else 'Break in' end as Status 
from @x as clocktran inner join minmax 
   on clocktran.emp_code = minmax.emp_code
  and clocktran.trandate = minmax.trandate 
where clocktran.emp_code = 1 and clocktran.trandate = '20220607'
order by clocktran.punch_time
;

fiddle to demonstrate. At the bottom of the script is another statement using the analytical versions of min/max. I leave it to you to adapt that to a complete solution. Use of row_number is another (but less obvious and slightly more complex) technique that can be applied. Much depends on the consistency and quality of your transaction data.

  • Related