8

I need my model to return only those records from one table where a matching record does not exist in another table. I was thinking that the solution might be with Query Scopes but the documentation only scratches the surface. So my SQL would look something like this:

SELECT *
FROM A
WHERE NOT EXISTS (SELECT A_id FROM B
                WHERE B.A_id = A.id)

Here are my tables:

A
-------------
| id | name |
-------------

B
--------------------
| id | A_id | name |
--------------------

Probably unnecessary but here are my models. Model for A:

class A extends Eloquent{

    public function B(){
        return $this->hasOne('B', 'A_id', 'id');
    }
}

Model for B:

class B extends Eloquent{

    public function A(){
        return $this->belongsTo('B', 'A_id', 'id');
    }
}

1 Answer 1

15

Something like

A::whereNotExists(function($query)
            {
                $query->select(DB::raw(1))
                      ->from('B')
                      ->whereRaw('A.id = B.id');
            })
            ->get();
Sign up to request clarification or add additional context in comments.

11 Comments

I need the opposite of the has method. (Is there a hasNot() method?)
I did find the whereNotExists method and I'm working with that now. But I'm finding a problem: In the whereRaw I have to use the entire table name (prefix and all) I'd don't want my prefix to be found anywhere in my code.
Also, I'm guessing that your code above should be in the Controller. Is there a way to do it in the Model?
You can put it in a query scope method containing: return static::whereNotExists(function($query) { $query->select(DB::raw(1)) ->from('B') ->whereRaw('A.id = B.id'); }) ->get();
This worked: scopeName($query){return $query->whereNotExists(function($query){$this_table = DB::getTablePrefix() . $this->table; $query->select(DB::raw('A_id')) ->from('B') ->whereRaw('A_id = '.$this_table.'.id'); })} Thank you
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.