How to pass a variable in join query in Laravel - sql

I have a variable that I would like to pass in a joined RAW query. How can I do that ?
$current_user_id = Auth::user()->id;
$query = DB::table('users as u')
->selectRaw('
ROW_NUMBER() OVER (ORDER BY u.id) AS No,
u.id,
u.username,
l.level AS Rank
')
->leftjoin(DB::raw('(
SELECT
u.id as ts_user_id,
u.username as ts_username,
u.email as ts_email,
l.downline_user_id AS ts_downline_user_id ,
outer_u.username AS ts_downline_username,
sum(o.pay_amount) AS ts_team_sales
FROM
users as u
INNER JOIN user_levels AS l
ON l.upline_user_id = u.id
INNER JOIN users as outer_u
ON outer_u.id = l.downline_user_id
LEFT JOIN user_levels as downline_level
ON l.downline_user_id = downline_level.upline_user_id
INNER JOIN users as outerdownline__u
ON outerdownline__u.id = downline_level.downline_user_id
LEFT JOIN orders as o
ON o.user_id = downline_level.downline_user_id
WHERE o.status = 1 AND downline_level.level > 1 AND u.id=1 **//HOW to pass the $current_user_id variable here**
GROUP BY l.downline_user_id
)RESULT_TEAM_SALES') , 'RESULT_TEAM_SALES.ts_downline_user_id' , 'l.downline_user_id')
->where('u.id' , $current_user_id)
->groupBy('l.downline_user_id')
->get()
I would like to replace Where u.id = $current_user_id . Is passing the variable possible ?
Please advise.
Thank you.

Do something like
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.column', '=', $yourVariable);
})
->get();
https://laravel.com/docs/9.x/queries

So, this is how I solved it. I made a sub query
$current_user_id = Auth::user()->id;
$teamSales= DB::table('users as u')
->selectRaw('
u.id,
u.username as ts_username,
l.downline_user_id AS ts_downline_user_id ,
outer_u.username AS ts_downline_username,
sum(o.pay_amount) AS ts_team_sales
')
->join('user_levels as l' , 'u.id' , '=' , 'l.upline_user_id')
->join('users as outer_u' , 'outer_u.id' , '=' , 'l.downline_user_id')
->leftJoin('user_levels as downline_level' , 'l.downline_user_id' , '=' , 'downline_level.upline_user_id')
->leftJoin('orders as o' , 'o.user_id' , '=' , 'downline_level.downline_user_id')
->where('o.status' , '=' , 1)
->where('downline_level.level' , '>' , 1)
->where('u.id' , '=' , $current_user_id)
->groupBy('l.downline_user_id')
;
Then used leftJoinSub method to left join the sub query
$query = DB::table('users as u')
->selectRaw('
ROW_NUMBER() OVER (ORDER BY u.id) AS No,
u.id,
u.username,
team_sales.ts_team_sales
')
->join('user_levels as l' , 'l.upline_user_id' , '=' , 'u.id')
->leftJoinSub($teamSales , 'team_sales' , function($join) {
$join->on('l.downline_user_id', '=', 'team_sales.ts_downline_user_id');
})
->where('u.id' , $current_user_id)
->groupBy('l.downline_user_id')
->get();

Related

Eloquent 2 left join query

I would like to execute the following query using Laravel's eloquent query builder:
SELECT a.*, b.day, c.sex FROM hours as a
left join reserves as b
on a.id = b.hour_id and b.day = '2015-12-12'
left join doctors as c
on a.doctor_id = c.id
where a.doctor_id = 1;
I have tried the following:
Hour::leftJoin('reserves', function($join) {
$join->on('hours.id' , '=' , 'reserves.hour_id')
->where('reserves.day' , '=' , '2015-12-12');
})
->leftJoin('doctors', function($join) {
$join->on('hours.doctor_id', '=', 'doctors.id');
})
->where('hours.doctor_id', '=', $doctorId)
->get();
Unfortunately, I am not getting the same results.
Everything looks fine, however you miss selecting columns, after Hour:: you should add:
select('hours.*'.'reserves.day','doctors.sex')->
You could also make second join simpler and use aliases, so the final code could look like this:
Hour::select('hours.*'.'reserves.day','doctors.sex')
->from('hours AS a')
->leftJoin('reserves AS b', function($join) {
$join->on('a.id' , '=' , 'b.hour_id')
->where('b.day' , '2015-12-12');
})
->leftJoin('doctors AS c', 'a.doctor_id', '=', 'c.id')
->where('a.doctor_id', $doctorId)
->get();
Of course as $doctorId you should set 1 to get exact same result
you can use DB::raw :
Hour::select(DB::raw('hours.*'),reserves.day, c.doctors)
->leftJoin('reserves',DB::raw("hours.id = reserves.hour_id AND reserves.day='2015-12-12'") ,DB::raw(''), DB::raw(''))
->leftJoin('doctors','hours.doctor_id', '=', 'doctors.id')
->where('hours.doctor_id', '=', $doctorId)
->get()
the 2 empty DB::raw is because leftJoin expect 4 arguments(table,columnA,operator,columnB)

Convert SQL query with inner, left, and nested select to LINQ

how can convert this query to linq?
SELECT p.PostID, p.PostText, p.PublishDate, u.Name
FROM AspNetUsers u INNER JOIN Posts p ON u.Id = p.PostUserID LEFT JOIN Reposts r ON p.PostID = r.PostID
WHERE p.PostUserID = 'id'
OR p.PostUserID IN ( SELECT FollowingUserID FROM Friends WHERE FollowerUserID = 'id' AND isUnfollow = 0)
OR p.PostID in (SELECT PostID FROM Reposts WHERE RepostUserID = 'id' OR RepostUserID IN ( SELECT FollowingUserID FROM Friends WHERE FollowerUserID = 'id' AND isUnfollow = 0))
ORDER BY p.PostUserID
Does this work?
var results = from u in AspNetUsers
join p in Posts on u.Id equals p.PostUserID
join r in Reposts on p.PostId equals r.PostId into records
from record in records.DefaultIfEmpty()
where p.PostUserID == "id"
|| (from friend in Friends
where friend.FollowerUserID == "id"
&& friend.isUnfollow == 0
select friend.FollowingUserID
).Contains(p.PostUserID)
|| (from r2 in Reposts
where r2.RepostUserID == "id"
|| (from friend2 in Friends
where friend2.FollowerUserID == "id"
&& friend2.isUnfollow == 0
select friend2.FollowingUserID
).Contains(r2.RepostUserID)
select r2.PostID
).Contains(p.PostID)
orderby p.PostUserID ascending
select p.PostID, p.PostText, p.PublishDate, u.Name;

Zend select object - building a query

How can I write the query below in Zend Select object notation so using ->join()->where() etc?
SELECT t.id, t.user_id, t.added_date, u.id, u.phone, bk.call_status
FROM `transaction` t
INNER JOIN
(
SELECT id, MAX(added_date) AS addedDate
FROM `transaction`
GROUP BY id
) gt
ON t.id = gt.id AND t.added_date = gt.addedDate
LEFT JOIN `user` u ON t.user_id = u.id
LEFT JOIN `bok_call` bk ON bk.user_id = t.user_id
WHERE NOT t.user_id = 'null'
AND addedDate BETWEEN '2008-05-04 17:51:48' AND '2009-05-04 17:51:48'
AND NOT u.phone = ''
AND bk.call_status IS null
For example this way:
$joinSelect = $model->select()
->from('transaction'), array('id', 'addedDate' => 'MAX(added_date)'))
->group('id');
$select = $model->select()
->setIntegrityCheck(false)
->from(array('t' => 'transaction'), array('id', 'user_id', 'added_date'))
->join(array('gt' => $joinSelect), 't.id = gr.id AND t.added_date = gt.addedDate', array());
->joinLeft(array('u' => 'user'), 't.user_id = u.id', array('id', 'phone'))
->joinLeft(array('bk' => 'bok_call'), 'bk.user_id = t.user_id', array('call_status'))
->where('t.user_id != ?', 'null')
->where("addedDate BETWEEN '2008-05-04 17:51:48' AND '2009-05-04 17:51:48')
->where('u.phone != ?', '')
->where('bk.call_status IS NULL');
Be aware that you won't be able to differentiate 't.id' and 'u.id' in result.

Converting SQL to LINQ to Entity

I am trying to convert the following SQL, not written by myself, into a Linq to Entity query.
select
u.user_Id,
u.forename,
u.surname,
u.client_code,
u.user_name,
u.password,
u.email,
u.gender,
u.Report_Date,
u.EmailDate,
count(ut.test_Id) as testcount,
sum(cast(isnull(ut.completed,0) as int)) as Testcompleted,
u.job_function,
lu.lookupvalue
from
users u inner join user_Relationship ur
on u.user_Id= ur.child_Id
left join user_tests ut
on ut.user_id=u.user_id
inner join lookup lu on u.first_languageId = lu.lookupid
where ur.parent_Id = #Parent_Id
group by
u.user_Id, u.forename,u.surname,u.client_code,u.user_name, u.password,
u.email, u.gender, u.first_languageId, u.Report_Date,u.EmailDate,
u.job_function, lu.lookupvalue
So far, I have been able to do this:
from u in db.Users
join ur in db.User_Relationship on u.User_ID equals ur.Child_ID
join ut in db.User_Tests on u.User_ID equals ut.User_ID into ps
from ut in ps.DefaultIfEmpty()
join lu in db.Lookups on u.First_LanguageID equals lu.LookupID
where ur.Parent_ID == 45875
select new UserViewModel
{
User_ID = u.User_ID,
Forename = u.Forename,
Surname = u.Surname,
Client_Code = u.Client_Code,
User_Name = u.User_Name,
Password = u.Password,
Email = u.Email,
Gender = u.Gender,
Report_Date = u.Report_date,
Email_Date = u.EmailDate,
//Insert Test_Count and Test_Completed
Job_Function = u.Job_Function,
Lookup_Value = lu.LookupValue
});
How do I replicate the Group and Count() function of SQL?
Well tweak around this solution coz currently i dont have .Net environment for testing this solution, but you'll sure get how grouping is done in linq.
from u in db.Users
join ur in db.User_Relationship on u.User_ID equals ur.Child_ID
join ut in db.User_Tests on u.User_ID equals ut.User_ID into ps
from ut in ps.DefaultIfEmpty()
join lu in db.Lookups on u.First_LanguageID equals lu.LookupID
where ur.Parent_ID == 45875 group new{u,lu} by new {u.User_ID,u.Forename,
u.Surname,u.Client_Code,
u.User_Name,u.Password,
u.Email,u.Gender,u.Report_date,
u.EmailDate,u.Job_Function,
lu.LookupValue} into g
let Test_Count = ps.Count(x=>x.test_Id)
let Test_Completed = ps.Sum(x=>x.completed)
select new UserViewModel
{
User_ID = g.Key.User_ID,
Forename = g.Key.Forename,
Surname = g.Key.Surname,
Client_Code = g.Key.Client_Code,
User_Name = g.Key.User_Name,
Password = g.Key.Password,
Email = g.Key.Email,
Gender = g.Key.Gender,
Report_Date = g.Key.Report_date,
Email_Date = g.Key.EmailDate,
Test_Count = Test_Count,
Test_Completed = Test_Completed,
Job_Function = u.Job_Function,
Lookup_Value = lu.LookupValue
});

Error in FROM clause: near '{'. Unable to parse query text

I'm trying to execute the following query for a Dataset:
SELECT
S.CUSIP, S.SecName,
ISNULL(RA.FinInstCode, '') AS RemarketingAgent,
S.IssueDate, S.MaturityDate, F2.FinInstName AS Trustee,
CASE WHEN SC1.ExpirationDate IS NULL
THEN '' ELSE ISNULL(F1.FinInstCode, '') END
AS CreditProvider,
CASE WHEN SC1.ExpirationDate IS NULL
THEN '' ELSE ISNULL(C1.CreditEnhancementCode, '') END
AS CreditType,
SC1.ExpirationDate AS CreditExpirationDate,
SC1.RefNum AS RefNumber
FROM
dbo.SecurityCreditEnhancementProvider SC1,
dbo.FinInst F1,
dbo.LUCreditEnhancement C1,
{ oj { oj dbo.Security S
LEFT OUTER JOIN
dbo.FinInst F2 ON S.TrusteeID = F2.FinInstID }
LEFT OUTER JOIN
dbo.FinInst RA ON S.RemarketingAgentID = RA.FinInstID }
WHERE
S.SecID = SC1.SecID
AND
SC1.CreditProviderID = F1.FinInstID
AND
SC1.CreditEnhancementID = C1.CreditEnhancementID
AND
C1.CreditEnhancementCode = 'LOC' OR
C1.CreditEnhancementCode = 'LIQUIDITY'
AND
(S.ActiveFlag = 'A')
AND
(S.SecTypeID NOT IN (4, 7))
ORDER BY CreditExpirationDate
When trying to run the query the error I get is " Error in FROM clause near:
'{' . Unable to parse query. "
Any help to fix this issue would be most appreciated.
Thanks,
EDIT 1: This is what is looks like after query designer changes the code:
FROM { oj { oj { oj { oj { oj dbo.SecurityCreditEnhancementProvider SC1 LEFT OUTER JOIN
dbo.FinInst F1 ON SC1.CreditProviderID = F1.FinInstID } LEFT OUTER JOIN
dbo.LUCreditEnhancement C1 ON SC1.CreditEnhancementID = C1.CreditEnhancementID } LEFT OUTER JOIN
dbo.Security S ON S.SecID = SC1.SecID } LEFT OUTER JOIN
dbo.FinInst F2 ON S.TrusteeID = F2.FinInstID } LEFT OUTER JOIN
dbo.FinInst RA ON S.RemarketingAgentID = RA.FinInstID }
Thanks all for there help.
Formatting code in a case like this might be helpful. you had incorrect syntax in your FROM clause. I also updated the query to use JOIN Syntax on all tables instead of using commas between your tables.
SELECT S.CUSIP
, S.SecName
, ISNULL(RA.FinInstCode, '') AS RemarketingAgent
, S.IssueDate
, S.MaturityDate
, F2.FinInstName AS Trustee
, CASE WHEN SC1.ExpirationDate IS NULL THEN '' ELSE ISNULL(F1.FinInstCode, '') END AS CreditProvider
, CASE WHEN SC1.ExpirationDate IS NULL THEN '' ELSE ISNULL(C1.CreditEnhancementCode, '') END AS CreditType
, SC1.ExpirationDate AS CreditExpirationDate
, SC1.RefNum AS RefNumber
FROM dbo.SecurityCreditEnhancementProvider SC1
LEFT JOIN dbo.FinInst F1
ON SC1.CreditProviderID = F1.FinInstID
LEFT JOIN dbo.LUCreditEnhancement C1
ON SC1.CreditEnhancementID = C1.CreditEnhancementID
LEFT JOIN dbo.Security S
ON S.SecID = SC1.SecID
LEFT OUTER JOIN dbo.FinInst F2
ON S.TrusteeID = F2.FinInstID
LEFT OUTER JOIN dbo.FinInst RA
ON S.RemarketingAgentID = RA.FinInstID
WHERE (C1.CreditEnhancementCode = 'LOC' OR C1.CreditEnhancementCode = 'LIQUIDITY' )
AND (S.ActiveFlag = 'A')
AND (S.SecTypeID NOT IN (4, 7))
ORDER BY CreditExpirationDate