Subquery in laravel query builder - laravel

How could I do this query in laravel:
SELECT * FROM(
SELECT * FROM `tb_horario` where cod_funcionario="'.$cod.'" and deleted_at is null)
AS temp
where temp.motivo!='' or temp.validado=0
but sometimes I dont have to use cod_funcionario because is a filter in my page
so I've something like:
if ($funcionario)
{
$horariosQuery->where('cod_funcionario', $funcionario);
}
I dont know how to do this query with this subquery in laravel like I did in sql.
thxx!

$horariosQuery = $this->horario->with(array('funcionario', 'item_contabil'))
->whereNull('deleted_at')
->orderby('cod', 'ASC');
if ($funcionario)
{
$horariosQuery->where('cod_funcionario', $funcionario)
->where(function ($query) {
$query->where('validado', 0)
->orWhere('motivo', '!=', '');
})
->orderBy('data');
}
else
{
$horariosQuery->where('validado', 0)
->orWhere('motivo', '<>', '')
->orderBy('cod_funcionario');
}

Related

Laravel Parameter Grouping (and/or where)

I upgraded Laravel to version 7, and when I do a query like this:
$users = User::where('name', '=', 'John')
->where(function ($query) {
$query->where('votes', '>', 100)
->orWhereNull('title');
})
->get();
it doesn't work as expected, and I got this error [SQL Server] Must specify table to select from
because the SQL should be like this:
select * from users where name = 'John' and (votes > 100 or title is null)
but when I debug the returned query it shows like this:
select * from users where name = 'John' and (select * votes > 100 or title is null) is null
The above query it just an example of my complex query, and I have a lot like this query in all of my project so I don't need a replacement, I just need to know how to fix it as it worked fine before upgrading
You can use whereRaw for the alternative method, for example
$users = Table::whereRaw(" name=? AND (votes=? OR title=?)", array(?,?,?))
$users = User::where('name', '=', 'John')
->where(function ($query) {
$query->from('users')
->where('votes', '>', 100)
->orWhereNull('title');
})
->get();

Convert SQL query into Laravel query builder

I need to convert this query into laravel query builder
select * from employee where(( age = 25 and salary = 20000) or (age =30 and salary = 30000))
If you want to group where clauses you can nest them inside closures:
DB::table('employee')
->where(function ($query) {
$query->where('age', 25)->where('salary', 20000);
})
->orWHere(function ($query) {
$query->where('age', 30)->where('salary', 30000);
})
->get();
For more information have a look at Parameter Grouping in the documentation.
Can you try this,
$data = Model::where([["age", "25"],["salary", "20000"]])
->orWhere([["age", "30"],["salary", "30000"]])
->get();

Query builder with max()

I am trying to rewrite this sql to laravel 4
SELECT
*
FROM
SolutionFile
WHERE
SolutionFile.group_id = $group_id and
version = (
SELECT
max(s1.version)
FROM
SolutionFile s1
WHERE
s1.group_id = $group_id
)
I wrote this request
SolutionFile::where('group_id', '=', $group_id)
->whereRaw('version = (select max(`version`) from files where group_id = ' . $group_id . ')')->get();
which works perfectly, but I want to rewrite it in "laravel way" without whereRaw.
I tried this request
SolutionFile::where('group_id', '=', $group_id)
->where(function($query) use($group_id) {
return $query->where('version', '=', function() use($group_id) {
return SolutionFile::where('group_id', '=', $group_id)->max('version');
});
});
but it returns an empty set.
Is there any way to rewrite it? Where did I make a mistake in last request?
I found simple solution for this
SolutionFile::where('group_id', '=', $group_id)
->where(function($query) use($group_id) {
return $query->where('version', '=', SolutionFile::where('group_id', '=', $group_id)->max('version'));
})->get()
There was no need to use function() as third param, only result from this function.

Laravel query builder not replacing question mark

I'm running the following query:
return $this->hasMany('App\Task', 'company')
->whereNotIn('id', function($query)
{
$query->from('tasks')->join('projects', function($join)
{
$join->on('projects.id', '=', 'tasks.project')
->where('projects.status', '=', Project::STATUS_ARCHIVED);
})
->select('tasks.id');
});
But if I output the whole raw query I get the following:
select * from `tasks` where `tasks`.`company` = 1 and `id` not in (select `tasks`.`id` from `tasks` inner join `projects` on `projects`.`id` = `tasks`.`project` and `projects`.`status` = ?)
As you can see at the end of the raw query there's a question mark that wasn't replaced with the actual value, instead 'tasks'.'company' = 1 was.
You can listen to the illuminate.query event. Before the query add the following event listener:
use Event;
Event::listen('illuminate.query', function($query, $params, $time)
{
dd([
$query, // prepared statement
$params, // query params (? symbols will be replaced with)
$time // execution time
]);
});
I found a solution to this issue by manually setting the bindings using
->setBindings([Project::STATUS_ARCHIVED]);
Here's the whole snippet:
return $this->hasMany('App\Task', 'company')
->whereNotIn('id', function($query)
{
$query->from('tasks')->join('projects', function($join)
{
$join->on('projects.id', '=', 'tasks.project')
->where('projects.status', '=', '?');
})
->select('tasks.id')
->setBindings([Project::STATUS_ARCHIVED]);
})
->where('status', '=', Task::STATUS_INCOMPLETE);
You didn't add ->get(); to the end of the query.
Try:
return $this->hasMany('App\Task', 'company')
->whereNotIn('id', function($query)
{
$query->from('tasks')->join('projects', function($join)
{
$join->on('projects.id', '=', 'tasks.project')
->where('projects.status', '=', Project::STATUS_ARCHIVED);
})
->select('tasks.id');
})->get();

query with Laravel Eloquent ORM

How can I make this query in Laravel, using Eloquent ORM?
select * from posts p order by ( select count(*) from likes where flag = 'c' and p.id = post_id ) Desc limit 3
I have this relationship in my models
Post.php
public function likes(){
return $this->hasMany('Like', 'post_id');
}
Like.php
public function post(){
return $this->belongsTo('Post', 'post_id');
}
Thanks! :)
You may try something like this:
$posts = Post::leftJoin('likes', function($join) {
$join->on('posts.id', '=', 'likes.post_id')->where('flag', '=', 'c');
})
->select('posts.*', 'likes.post_id', DB::raw('count(likes.post_id) as pCount'))
->groupBy('post_id')
->orderBy('pCount', 'desc')
->take(3)
->get();

Resources