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

ollie_123's avatar

Help with a join query

Hi All

I'm a little stuck on a join query and was wondering if i'm barking up the wrong tree. In my app i have brands and products. Brands have options & sub options which can then be assigned to the product options & sub options which are related to the product (to save having to re create the options etc for each product).

At the moment i've got it working and have assigned brand options & sub options to product A but when i go to product B its only showing the brand options that have been assigned to Product A and i think this is an issue with the join.

Here's what i've got:-

$brandOptions = \DB::table('brand_options')
    ->join('product_options', 'brand_options.id', '=', 'product_options.brand_option_id')
    ->select('brand_options.*', 'product_options.brand_option_id', 'product_options.product_id')
    ->where('product_options.brand_option_id', '!=', 'brand_options.id')

    ->where('brand_options.brand_id', $this->brand)
    ->where('product_options.product_id', '!=', $product)
    ->get();

But what i'm looking to do is to show all brand options that aren't assigned to that particular product on the product options table so that they can then be assigned.

Any questions, please let me know. Thanks in advance folks.

0 likes
22 replies
ollie_123's avatar

@sr57 Thanks, i'll have a look into intersect and i will let you know if i get stuck.

Relationships are also set up as one to many ;)

lat4732's avatar

What are you getting when you dd($brandOptions)?

ollie_123's avatar

@Laralex Hey @laralex when i dd i get the brand options that are associated to another product on the product_options table and not all of the brand options available that arent assigned with that product.

Any questions, please let me know.

lat4732's avatar

@ollie_123 Please, give me a screenshot of an example result of dd($brandOptions). Also why are you selecting product_options.brand_option_id. What's the point of that?

->select('brand_options.*', 'product_options.brand_option_id', 'product_options.product_id')

and I still can't understand whats wrong with your query and result.

ollie_123's avatar

@Laralex i selected product_options.brand_option_id as later in the query i wanted to exclude any brand options that match that particular product ->where('product_options.brand_option_id', '!=', 'brand_options.id').

For the dd its now showing an empty array but if i put the variable into blade it chucks out the data from the query:-

[{"id":9,"uuid":"d20bf80cb79d255ea96b2ff01a6fd31e1354c2ad03263","brand_id":19,"attribute_name":"Options","status":"1","created_at":"2022-05-03 21:17:38","updated_at":"2022-05-03 21:17:38","brand_option_id":9,"product_id":1144},

{"id":12,"uuid":"94b9175d2a3a2eac3d258f3abf39909612857ce312f33","brand_id":19,"attribute_name":"Protocols (Slave Unit)","status":"1","created_at":"2022-05-29 16:04:59","updated_at":"2022-05-29 16:04:59","brand_option_id":12,"product_id":1144}]

Thanks in advance

ollie_123's avatar

Hi All

After many hours and trying different ways of pulling the correct data, i'm still stuck on this.

Is an inner join the best way to go or is there a better solution.

Thanks in advance.

sr57's avatar

@ollie_123

Did you test intersect? Should be good to have your feedback ...

ollie_123's avatar

Hey @sr57, i tried intersect but i don't think its quite right as its just returning all values from the brand_options table whereas i need to exclude all options from the brand_options table that match the values on the product_options table leaving only un assigned brand_options to be assigned.

$brandOptions = BrandOption::where('brand_id', $this->brand)->get();
$productOptions = ProductOption::get();

$collection = collect([$brandOptions, $productOptions]);
$intersect = $collection->intersect([$brandOptions]);

Any questions, please let me know. Thanks in advance.

ollie_123's avatar

Hi @sr57, thanks for this. Using diff i'm getting an undefined error in my blade foreach so i'm guessing its an empty array.

Does this work using the foreign keys in the ProductOption model i.e belongsTo(BrandOption::class, 'brand_option_id'?

This is where im currently at with the diff

$bo = BrandOption::where('brand_id', $this->brand)->get();
$po = ProductOption::where('product_id', $this->pid)->get();
        
$collection = collect([$bo, $po]);
$brandOptions = $collection->diff($po);

if you could advise where i might be going wrong it would be much appreciated.

Thanks in advance.

sr57's avatar
sr57
Best Answer
Level 39

@ollie_123

all brand options that aren't assigned to that particular product

all brand options

     $bos=BrandOption::pluck('id')

don't understand why you filter by $this->brand in your code

product options

     $product_bos=ProductOption::where('product_id', $this->pid)->pluck('brand_option_id');

all brand options that aren't assigned to that particular product

     $bos_available = $bos->diff($product_bos);
1 like
ollie_123's avatar

Hey @sr57

So the don't understand why you filter by $this->brand in your code is so i can filter down the brand options based on the product brand.

If i dd currently i get:-

 #items: array:11 [▼
    0 => 1
    1 => 2
    2 => 3
    3 => 4
    4 => 5
    5 => 6
    6 => 7
    7 => 8
    8 => 9
    9 => 10
    10 => 12
sr57's avatar

@ollie_123

Step after step, does $bos_available returns the right values?

For your blade error, it's another pb, probably because you have to complete my answer with the option names ...

Share your controller and blade code if needed ... better in another thread (one question per thread and I have to leave now)

ollie_123's avatar

Hey @sr57 TBH the array just shows the numbers incrementing which align with the brand options table but not the product options table.

I currently have...

For the controller/component:-

$bo = BrandOption::pluck('id');
$po = ProductOption::where('product_id', $this->pid)->pluck('brand_option_id');
$brandOptions = $bo->diff($po);

For the blade:-

@foreach($brandOptions as $option)
<div class="flex items-center py-2">
    <input type="checkbox" required value="{{ $option->id }}" wire:model="option_id_arr">
    <div class="form-input-label">{{ $option->attribute_name }}</div>
</div>.....

Also i didnt want to start a new thread as this is the same question i posted initially. ;)

Any questions, please let me know. Thanks in advance.

sr57's avatar

@ollie_123

the array just shows the numbers incrementing which align with the brand options table but not the product options table.

So it was you are looking for ?

As I wrote before, the blade cannot work with that query that returns only the id, you have to add the name (attribute_name)

ollie_123's avatar

@sr57

"So it was you are looking for ?" Unfortunatley not quite, for example, on the View Product Page where i can add options to the product, i already have options associated to the product but when i go to add more and dd the array it shows all options from the brand_options table so doesnt appear to be filtering out the brand_options already associated.

If you wanted me to show the table layouts please let me know as sometimes i don't explain myself too well lol.

Thank you in advance.

sr57's avatar

@ollie_123

Communication is always a difficult art and it seems that I can't get your need or you don't understand my/our answers. Personally I'll be rarely here next days, I suggest you to reread all the answers you got, normally you should be able to find the solution by yourself, if not, try rephrase your need the simpler as possible ( 1 step / 1 question). Good luck.

ollie_123's avatar

Hey @sr57, no worries, i appreciate you taking the time to help on this. I managed to get it working in the end with a couple of queries but you definitely helped me in the right direction so will mark your post as best answer.

Thanks again for your help. Much appreciated.

Please or to participate in this conversation.