Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

frittate's avatar

Query one-to-many relationship

Hey everyone, I'm trying to write a rather simple query. My voucher table has a number of vouchers, and each voucher is connected to multiple logs in the log table.

I can easily get the vouchers that have a certain log status (say [10]) like this:

$status = $query['status'];
$source = $query['source'];
$results = Voucher::whereHas('logs', function ($q) use($status) {
  $q->whereIn('status', $status);
})
->whereIn('source', $source)
->get();

However, this will return all logs with the status 10. My question is how can I get the vouchers whose logs ONLY have the status 10, but no others?

So the code now returns all voucher logs that have status 10 or more.

status = [10]

  1. Voucher #1: logs: [status: 10, status: 30]
  2. Voucher #2: logs: [status: 10]
  3. Voucher #3: logs: [status: 10, status: 30, status: 50]

-> this should only return Voucher #2

I want to pass an array that ONLY returns if all those codes in the array are met, not if others are also present.

0 likes
1 reply
ahmeddabak's avatar
$status = $query['status'];
$source = $query['source'];
$results = Voucher::whereHas('logs', function ($q) use($status) {
  $q->whereIn('status', $status)->havingRaw('COUNT(id) = ?', [count($status)]);
})
->whereIn('source', $source)
->get();

Please or to participate in this conversation.