How to make Multiple sub query in Laravel - laravel

I am new in Laravel.
Here below i mention my code how to make this in laravel query builder.
Using tables are ab,cd,ef,gh,ij
SELECT ab.* FROM ab
WHERE ab.id IN (
SELECT ab_id FROM cd
WHERE ef_id = 1 AND status = 1
AND deleted_at IS NULL
AND ab_id IN (
SELECT ab_id FROM gh
WHERE ij_id IN (
SELECT id FROM ij
WHERE ef_id = 1 AND deleted_at IS NULL
) AND deleted_at IS NULL
) AND ab_id IN (
SELECT id FROM ab
WHERE deleted_at IS NULL AND usertest != 1
)
)AND ab.deleted_at IS NULL
GROUP BY ab.id
ORDER BY ab.created_at DESC;

You can pass a closure to a where condition and query another table.
From the Laravel docs:
DB::table('users')
->whereExists(function ($query) {
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id');
})
->get();

Related

sql query into raw query in laravel

I am new in laravel . I have laravel 5.7 version. and I have query
like
$emp_id = $request->user_id;
$User_workDone_record = DB::select(
DB::raw("
SELECT
(
SELECT access(id) FROM users where id = $emp_id
) as accessid,
a.date as date,
a.day as day,
a.projectname as projectname,
a.clientname as clientname,
task,
start,
(
SELECT users(id) FROM `users` where id = $emp_id
) as user,
end,
TIMEDIFF(end,start) as diff,
workdetails,
id,
rowpages
FROM
workdone as a
where
a.user = '$emp_id'
order by
a.date desc
")
);
but I got issue like :
SQLSTATE[42000]: Syntax error or access violation: 1305 FUNCTION workdoneerp.access does not exist (SQL: SELECT(SELECT access(id) FROM users where id=9) as accessid, a.date as date,a.day as day,a.projectname as projectname,a.clientname as clientname,task,start,end,TIMEDIFF(end,start) as diff,workdetails,id,rowpages FROM workdone as a where a.user='9' order by a.date desc),
How to resolve ?
The problem is access(id) at the start of your SQL query.
The error is telling you the access() function does not exist in your database (workdoneerp).
To solve it you can
create the access() function
or don't use the access() function.

Laravel Eloquent Query With OR WHERE Condition

I am using Laravel 6 & mysql 7
I have below query
$tasks = Task::where('deleted_at', null)->where('company_id',$company_id);
$tasks = $tasks->where('created_by',$user_id);
$tasks = $tasks->orWhereIn('id',$task_ids);
It generates below raw query when i print it
SELECT * FROM `tasks` WHERE `deleted_at` IS NULL AND `company_id` = 25 AND `created_by` = 20 OR
`id` IN(112,...215) ORDER BY `id` DESC
Now Id 112 is deleted but still showing in result, although i have where('deleted_at', null) condition but it is not working
I want to apply all other conditions on $task_ids as well
How this can be achieved with optimized query?
UPDATED: Here is complete scenario
I want to select all records which is created by me or assigned to me. Here is my complete code.
$tasks = Task::where('deleted_at', null)->where('company_id',$company_id);
$tasks = $tasks->where('created_by',$user_id);
$task_ids = TaskUser::where('user_id',$user_id)->pluck('task_id')->all();
$tasks = $tasks->orWhereIn('id',$task_ids);
This is because the AND operator has a higher precedence than OR, which basically means that AND "sticks" together more than OR does. You query basically is interpredeted like this:
SELECT * FROM `tasks`
WHERE
(`deleted_at` IS NULL AND `company_id` = 25 AND `created_by` = 20)
OR
( `id` IN(112,...215) )
I am not entirly sure wheter you actually want to OR anything. If you really want to apply all conditions, you just need to change the orWhereIn to a whereIn.
In case you want all not-deleted tasks, that EITHER belong to a company and a auser OR whose id is in the list, you would need to update your query like this:
$tasks = Task::where('deleted_at', null);
$tasks = $tasks->where(function($q) use ($user_id, $task_ids){
$q->where(function($q2) use ($user_id, $task_ids) {
$q2->where('created_by',$user_id)
->where('company_id',$company_id);
})
->orWhereIn('id',$task_ids);
});
which should result in this query:
SELECT * FROM `tasks`
WHERE `deleted_at` IS NULL AND (
( `company_id` = 25 AND `created_by` = 20 )
OR
`id` IN(112,...215)
)
There is actually a chapter about parameter grouping in the excellent laravel documentation as well.

Using same table in subquery

I am failing to convert next SQL code into laravel eloquent:
SELECT t1.template, t1.created_at
FROM sent_emails t1
where created_at = (
select max(created_at) from sent_emails t2 where t2.template = t1.template
)
group by t1.created_at, t1.template
or:
SELECT t1.template, t1.created_at
FROM sent_emails t1
JOIN
(
SELECT Max(created_at) date, template
FROM sent_emails
GROUP BY template
) AS t2
ON t1.template = t2.template
AND t1.created_at = t2.date
group by t1.created_at, t1.template
Both queries return same data set. Creating subquery in separate variable is not an option as I need multiple values to be returned from it.
I also don't know how can I set alias name if I create table using models (and not using DB::), so this is my unsuccessful try:
$sent_emails = SentEmail::where('created_at', function($query) {
SentEmail::where('template', 't1.template')->orderBy('created_at', 'desc');
})->groupBy('template', 'created_at')->get(['template', 'created_at']);
You query should be something like this (I'm not at a computer to test this, so it may require further editing)
$sent_emails = SentEmail::where('created_at', function($query) {
$query->where('created_at', SentEmail::->whereColumn('column_name', 'table.column_name')->orderBy('created_at', 'desc')->max('created_at'));
})->groupBy('template', 'created_at')->get(['template', 'created_at']);

Raw Laravel query as a collection with conditions

I've got a fairly complex query that I'd rather not write in Eloquent so I've written it raw. The only problem is that I need to be able to search/filter through the data using the front-end this query is connected to.
This what I've tried but I'm getting an "Call to a member function get() on null" error.
Here's my code:
$report = collect(DB::connection('mysql2')->select("SELECT
t2.holder,
t2.merchantTransactionId,
t2.bin,
t2.last4Digits,
t3.expDate,
(CASE WHEN t3.expDate < CURDATE() THEN 'Expired'
WHEN t3.expDate > CURDATE() THEN 'Due to expire' END) AS expInfo,
t2.uuid
FROM transactions AS t2
INNER JOIN (
SELECT t1.uuid, t1.holder, t1.bin, t1.last4Digits, LAST_DAY(CONCAT(t1.expiryYear, t1.expiryMonth, '01')) AS expDate
FROM transactions t1
JOIN (SELECT t1.merchant_access
FROM total_control.users,
JSON_TABLE(merchant_access, '$[*]' COLUMNS (
merchant_access VARCHAR(32) PATH '$')
) t1
WHERE users.id = :userId
) AS t2
ON t1.merchantUuid = t2.merchant_access
WHERE t1.paymentType = 'RG'
AND t1.status = 1
) t3
ON t2.uuid = t3.uuid
WHERE t3.expDate BETWEEN DATE_SUB(CURDATE(), INTERVAL 30 DAY) AND DATE_ADD(CURDATE(), INTERVAL 30 DAY)
GROUP BY t2.holder, t2.bin, t2.last4Digits
ORDER BY t2.holder ASC", ['userId' => $request->userId]))
->when($request->search['holder'], function($q) use ($request) {
$q->where('t2.holder', 'LIKE', '%'.$request->search['holder'].'%');
})->get();
return $report;

using raw query in where methods makes error in query generation

I have an eloquent query as
Role::where("(company_id = Auth::user()->company_id or name = 'admin')and id in(2,3)")->pluck('name');
According to my eloquent the sql should be as
select `name` from `roles` where ( company_id = 1 or name = admin ) and id IN (2, 3) and `roles`.`deleted_at` is null
But it executes as
select `name` from `roles` where ( company_id = 1 or name = admin ) and id IN (2, 3) is null and `roles`.`deleted_at` is null
Can anyone help me concluding why extra is null condition is applied in the query?
Note: I am using soft deletes
You should use whereRaw instead of where
Role::whereRaw("(company_id = Auth::user()->company_id or name = 'admin')and id in(2,3)")->pluck('name');

Resources