У вас была правильная идея. Но, как утверждают другие, GROUP BY ваш лучший друг здесь. Кроме того, используйте DISTINCT, чтобы избавиться от счета официанта дважды для одного и того же заказа. Вот как должен выглядеть ваш код
// An inner select query whose purpose is to count all waiter per room
// The key here is to group them by `oid` since we are interested in the order
// Also, in the count(), use DISTINCT to avoid counting duplicates
$this->db->select('room.oid, count(DISTINCT room.waiter_assigned) AS total_waiters');
$this->db->from('room');
$this->db->group_by('room.oid');
$query1 = $this->db->get_compiled_select();
// If you run $this->db->query($query1)->result(); you should see
oid | total_waiters
----+-------------------------------
1 | 1
2 | 1
3 | 2
// This is how you would use this table query in a join.
// LEFT JOIN also considers those rooms without waiters
// IFNULL() ensures that you get a 0 instead of null for rooms that have no waiters
$this->db->select('order.oid, order.name, IFNULL(joinTable.total_waiters, 0) AS total_waiters');
$this->db->from('order');
$this->db->join('('.$query1.') joinTable', 'joinTable.oid = order.oid', 'left');
$this->db->get()->result();
// you should see
oid | name | total_waiters
----+-----------+-------------------------
1 | aa | 1
2 | bb | 1
3 | cc | 2
4 | dd | 0
Вот необработанный оператор SQL
SELECT order.oid, order.name, IFNULL(joinTable.total_waiters, 0) AS total_waiters
FROM order
LEFT JOIN (
SELECT room.oid, count(DISTINCT room.waiter_assigned) AS total_waiters
FROM room
GROUP BY room.oid
) joinTable ON joinTable.oid = order.oid