Home > Software design >  How to merge two rows with same column value into one row
How to merge two rows with same column value into one row

Time:10-30

I'm trying to fetch data using Codeigniter 4 and query builder. I have a table structure like below

id employee_id in_out time
1 EMP_001 in 08:10
2 EMP_001 out 10:30
3 EMP_002 in 09:15

I want to retrieve data and output to the view as single array, combining two rows of records into one like below

id employee_id in out
1 EMP_001 08:10 10:30
2 EMP_002 09:15

my current model is below

    $builder = $this->db->table('attendance');
    $builder->select('id, employee_id, in_out, time');
    $builder->select('id, employee_id, in_out, CONCAT(DATE_FORMAT(time, "%r"), '.', DATE_FORMAT(time, "%r")) AS clock_time', FALSE);
    $builder->groupBy('employee_id');
    $query = $builder->get()->getResult();

    return $query;

I'm trying to figure out using CONCAT or is there a better way?

CodePudding user response:

you can resolve this by joining (left join) your table attendance with itself.

The columns in and out are aliases from the column time. The first SELECTgets you all in values by each employee, which by your example has always a value.

Now we only need to add the out part, which is done via a LEFT JOIN, querying the table attendance again.

this is the raw MySQL query, which you can see working in this sqlfiddle

SELECT
    `t1`.`id`,
    `t1`.`employee_id`,
    `t1`.`time` AS `in`,
    `t2`.`time` AS `out`
FROM
    `attendance` `t1`
LEFT JOIN(
    SELECT
        *
    FROM
        `attendance`
    WHERE
        `in_out` = 'out'
) t2
ON
    `t1`.`employee_id` = `t2`.`employee_id`
WHERE
    `t1`.`in_out` = 'in'

this can be "translated" into a CI query using the CI Query Builder Class. Note the use of table aliases t1 and t2 as well as the column aliases in and out

$builder = $this->db->table('attendance t1');
$builder->select('t1.id, t1.employee_id, t1.time as in, t2.time as out');
$builder->join('(SELECT * FROM attendance WHERE in_out = "out") t2', 't1.employee_id = t2.employee_id', 'left')
$builder->where(t1.in_out, 'in');
$query = $builder->get()->getResult();

return $query;

while this is to answer your question How to merge two rows with same column value into one row you will need to prepare for several time attendance issues, like

  • multiple check-in/out from same employee at same day
  • check out after midnight (next day)
  • employee forgot to check in earlier and wants to check out
  • employee forgot to check out earlier and wants to check in

and probably others

  • Related