To nie jest pełna odpowiedź, ale jest blisko. Bez względu na to, jak pracuję z danymi, nie mogę zrozumieć, jak wymyślasz cash_has
. Zachowuję też surowy SQL, ponieważ uważam, że byłby bardziej pomocny i nie powinien być trudny do przekonwertowania z powrotem do konstruktora zapytań. Nie znam również dokładnych nazw kolumn, więc być może będziesz musiał poprawić niektóre z nich.
SELECT
COALESCE(outlets_admin.name, outlets.name) AS outlet,
COALESCE(boys_admin.name, boys.name) AS delivery_boy,
SUM(IF(cm.source_type = 'admin', amount, 0)) AS cash_taken,
SUM(IF(cm.source_type = 'deliveryBoy', amount, 0)) AS cash_returned,
SUM(IF(cm.source_type = 'admin', amount, 0)) - SUM(IF(cm.source_type = 'deliveryBoy', amount, 0)) AS cash_has
FROM delivery_cash_manages cm
LEFT JOIN outlets ON outlets.id = cm.destination_id AND cm.source_type = 'deliveryBoy'
LEFT JOIN delivery_boys boys ON boys.id = cm.source_id AND cm.source_type = 'deliveryBoy'
LEFT JOIN outlets outlets_admin ON outlets_admin.id = cm.source_id AND cm.source_type = 'admin'
LEFT JOIN delivery_boys boys_admin ON boys_admin.id = cm.destination_id AND cm.source_type = 'admin'
WHERE COALESCE(outlets.id, outlets_admin.id) = '2' # This is where you plug in your $outlet_id
GROUP BY outlet, delivery_boy
Powodem, dla którego pojawia się błąd w zapytaniu, jest to, że jeśli grupujesz według czegokolwiek, musisz pogrupować według wszystkiego, co wybierzesz, które nie są kolumnami zagregowanymi (funkcje takie jak suma, max, avg).