Assumption:
users
table has id
, name
, email
, password
fields.posts
table has id
, title
, body
fields.Question:
I want to get "users" who have posts whose title or body contain search queries.
My current code:
// example of search queries
$search_queries = ['aaa', 'bbb', 'ccc'];
// column names to search in MySQL
$search_column_names = [
'users.name',
'posts.title',
'posts.body'
];
$users = User::leftJoin('posts', 'users.id', '=', 'posts.user_id')
->orWhere(function($q) use ($search_queries, $search_column_names){
foreach ($search_column_names as $key => $name) {
$q->orWhere(function($q) use ($search_queries, $name){
foreach ($search_queries as $key => $search_query) {
$q->where($name, 'like', '%' . $search_query . '%');
}
});
}
})->distinct('users.id')->get();
but still I get more than 5 users with different id(up to 50). I though distinct(users.id)
gave me an ideal result, but it didn't work.
I searched through web already, but I couldn't find a solution.
Thanks in advance.
You can use a raw statement.
$users = User::whereRaw("id in(
select distinct user_id from posts
where title like :query or
body like :query
)" , ["query" => "%" . $search_query . "%"])->get();
I found a solution. I divided posts table searches into two whereIn
s. Thanks!
// column names to search in the database
$search_column_names = [
'users.name'
];
$users = User::
orWhere(function($q) use ($queries, $search_column_names){
foreach ($search_column_names as $key => $name) {
$q->orWhere(function($q) use ($queries, $name){
foreach ($queries as $key => $value) {
$q->orWhere($name, 'like', '%' . $value . '%');
}
});
}
})
->whereIn('users.id', function($q) use ($queries){
$q->select('user_id')
->from(with(new Post)->getTable())
->where(function($q2) use ($queries){
foreach ($queries as $key => $value) {
$q2->orWhere('posts.title', 'like', '%' . $value . '%');
}
});
}, 'or')
->whereIn('users.id', function($q) use ($queries){
$q->select('user_id')
->from(with(new Post)->getTable())
->where(function($q2) use ($queries){
foreach ($queries as $key => $value) {
$q2->orWhere('posts.body', 'like', '%' . $value . '%');
}
});
}, 'or')
->get();