how to write query with "with" using laravel eloquent - laravel

How to make with laravel a query with with like the example below
Thank you
with s as (select s.id from s)
select a.*
from a
left join s on s.id = a.s_id
...

WITH clauses are not supported by Eloquent. You can either pass in a raw query
$sql = <<<SQL
with s as (select s.id from s)
select a.*
from a
left join s on s.id = a.s_id
...
SQL;
$results = DB::select($sql);
Or use a package that adds this functionality like staudenmeir/laravel-cte
DB::query()
->withExpression('s', fn ($query) => $query->select('s.id')->from('s'))
->select('a.*')
->from('a')
->leftJoin('s', 's.id', 'a.s_id')
...

Related

PL-SQL how to inner join twice on the same table

I'm trying to make a query that joins a table twice for language purpose.
But SQL Developer always throws an error
Invalid Identifier in the SELECT
when I try to use the ALIAS of my table (table2 is invalid)
SELECT
table1.code Code,
table2.descr DescrFr,
table3.descr_en DescrEn
FROM
main_table table1
INNER JOIN
descr_table table2 ON table1.code = table2.code
AND table2.lang = 'fr'
INNER JOIN
descr_table table3 ON table1.code = table3.code
AND table3.lang = 'en'
I didn't find anything helpful for my case that could teach me what's wrong with my query.
EDIT
Tested asked by user but resulted with this error
Erreur SQL : ORA-00904: "TABLE3"."code" : identificateur non valide
SELECT
table1.code AS Code,
table2.descr AS DescrFr,
table3.descr AS DescrEn
FROM main_table table1
INNER JOIN descr_table table2 ON (table1.code = table2.code)
INNER JOIN descr_table table3 ON (table1.code = table3.code)
WHERE (table2.lang = 'fr' AND table3.lang = 'en');
Answer
The result is a facepalm... the initial query is working.. i was just using the wrong column name in the descr_table...
I don't know the version you are using but I guess you could try SELECT table1.code AS Code,.... And I would prefer not using so much INNER JOIN in your sql query rather would use at least one RIGHT JOIN or LEFT JOIN because you need to have a "main table" which has the highest priority.
AND of course there is something wrong I guess.
so your code would be fine in this way:
SELECT
table1.code AS Code,
table2.descr AS DescrFr,
table3.descr_en AS DescrEn
FROM
main_table AS table1
INNER JOIN
descr_table AS table2 ON (table1.code = table2.code)
INNER JOIN
descr_table table3 ON (table1.code = table3.code)
WHERE
(table2.lang = 'fr' AND table3.lang = 'en')
I'd avoid the double join altogether.
and never use aliases such as table1
This could be...
SELECT
main.Code,
descr.DescrFr,
descr.DescrEn
FROM
main_table main
INNER JOIN
(
SELECT
code,
MAX(CASE WHEN lang = 'fr' THEN descr END) AS DescrFr,
MAX(CASE WHEN lang = 'en' THEN descr END) AS DescrEn
FROM
descr_table
WHERE
lang IN ('fr', 'en')
GROUP BY
code
)
descr
ON descr.code = main.code
(And even then, from your description, you don't even need the outer join as the code exists in the descr_table.)

How can I convert mysql to laravel eloquent left join?

Mysql query like this :
SELECT a.id, a.name, b.TotalMeal, c.TotalCollection
FROM users a
LEFT JOIN (
SELECT user_id, SUM( breakfast + dinner + lanch ) AS TotalMeal
FROM meals
GROUP BY user_id) b ON a.id = b.user_id
LEFT JOIN (
SELECT user_id, SUM( amount ) AS TotalCollection
FROM collections
GROUP BY user_id) c ON a.id = c.user_id
LIMIT 0, 30
I want to convert it to Laravel eloquent, but I'm confused. I have Three tables. eg - users( id, name,email ..), meals( user_id, breakfast,lanch,dinner) and collections(user_id, amount) .
There is a little hack that uses withCount() to select sums of related tables which can be used in your scenario:
User::query()
->select([
'id',
'name',
])
->withCount([
'meals as total_meals' => function ($query) {
$query->select(DB::raw('SUM(breakfast + dinner + lunch)'));
},
'collections as total_collections' => function ($query) {
$query->select(DB::raw('SUM(amount)'));
},
])
->get();
In this query, withCount will perform the joins for you.

Laravel join with FIND_IN_SET

I am new to laravel 5.2,and i want to know more about laravel query builder,
actually i wants to know that how can i write this SQL Query in laravel
SQL -> select d.*, c.*, ct.*, a.*, b.*, m.* FROM tbl_deal d
INNER JOIN tbl_category c ON d.deal_category_id = c.category_id
INNER JOIN tbl_brand b ON d.deal_brand_id = b.brand_id
INNER JOIN tbl_member m ON m.member_id = d.deal_member_id
INNER JOIN tbl_city ct ON FIND_IN_SET(ct.city_id,d.deal_city)
LEFT JOIN tbl_outlet o ON FIND_IN_SET(o.outlet_id,d.deal_outlets)
LEFT JOIN tbl_area a ON a.area_id = o.outlet_area_id
Please, try the query like this:
$result = DB::table('table_name')
->leftJoin('tbl_country_city', 'table_name.quiz_id', '=', 'tbl_country_city.quiz_id')
->whereRaw('FIND_IN_SET('.$b.',field_name)')
->get();

Select single column from a row in Laravel?

How can I fetch a single column from a single row in Laravel 4?
Here's what I'm trying:
return DB::selectOne("
SELECT EXISTS(
SELECT *
FROM permissions p
JOIN role_permissions rp ON rp.permission_id=p.id
JOIN user_roles ur ON ur.role_id=rp.role_id
WHERE ur.user_id=? AND p.code=?
)
",[Auth::user()->id,$perm_code]);
selectOne returns this ugly object though:
object(stdClass)#297 (1) {
["EXISTS(
SELECT *
FROM permissions p
JOIN role_permissions rp ON rp.permission_id=p.id
JOIN user_roles ur ON ur.role_id=rp.role_id
WHERE ur.user_id=? AND p.code=?
"]=>
string(1) "0"
}
Is there something better?
Using PDO is ugly too:
$stmt = DB::getPdo()->prepare("
SELECT EXISTS(
SELECT *
FROM permissions p
JOIN role_permissions rp ON rp.permission_id=p.id
JOIN user_roles ur ON ur.role_id=rp.role_id
WHERE ur.user_id=? AND p.code=?
)
");
$stmt->execute([Auth::user()->id,$perm_code]);
return (bool)$stmt->fetchColumn();
Use this:
DB::table('users')->pluck('columname');
From the inline documentation:
/**
* Pluck a single column's value from the first result of a query.
*
* #param string $column
* #return mixed
*/
Is this what you are looking for?
DB::table('users')->select('columnName')->join('whatever',...,...,...)->take(1)->get();
Another example
DB::table('users')
->join('contacts', 'users.id', '=', 'contacts.user_id')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('columnName')
->take(1)
->get();
Raw didn't worked for you?:
return DB::select(DB::raw("
SELECT EXISTS(
SELECT *
FROM permissions p
JOIN role_permissions rp ON rp.permission_id=p.id
JOIN user_roles ur ON ur.role_id=rp.role_id
WHERE ur.user_id=? AND p.code=?
))
",[Auth::user()->id,$perm_code]);
And you can process that object to get what you want:
$result = DB::select(DB::raw("
SELECT EXISTS(
SELECT *
FROM permissions p
JOIN role_permissions rp ON rp.permission_id=p.id
JOIN user_roles ur ON ur.role_id=rp.role_id
WHERE ur.user_id=? AND p.code=?
) as exists)
",[Auth::user()->id,$perm_code]);
$result[0]->exists ? '1' : '0'
This is a test I just did here:
Route::any('test', ['as' => 'test', function()
{
$result = DB::select(DB::raw('select exists(select * from users) as exists;'));
dd($result[0]->exists ? '1' : '0');
}]);
Worked like a charm.
To fetch a single value from the first result, you can use \Illuminate\Database\Query\Builder::value. e.g.
$lastInvoice = DB::table('booking_groups')
->where('company_id','=',$booking->company_id)
->orderBy('invoice_number','desc')
->value('invoice_number');

Distinct on one column in linq with joins

I know we can get distinct on one column using following query:
I know we can get distinct on one column using following query:
SELECT *
FROM (SELECT A, B, C,
ROW_NUMBER() OVER (PARTITION BY B ORDER BY A) AS RowNumber
FROM MyTable
WHERE B LIKE 'FOO%') AS a
WHERE a.RowNumber = 1
I have used similar sql query in my case where i am joining multiple tables but my project is in mvc4 and i need linq to entity equivalent of the same. Here is my code:
select * from
(
select fp.URN_No,
ROW_NUMBER() OVER
(PARTITION BY pdh.ChangedOn ORDER BY fp.CreatedOn)
as num,
fp.CreatedOn, pdh.FarmersName, pdh.ChangedOn, cdh.Address1, cdh.State, ich.TypeOfCertificate, ich.IdentityNumber, bdh.bankType, bdh.bankName,
pidh.DistrictId, pidh.PacsRegistrationNumber, idh.IncomeLevel, idh.GrossAnnualIncome
from MST_FarmerProfile as fp inner join PersonalDetailsHistories as pdh on fp.personDetails_Id = pdh.PersonalDetails_Id
inner join ContactDetailsHistories as cdh on fp.contactDetails_Id = cdh.ContactDetails_Id
inner join IdentityCertificateHistories as ich on fp.IdentityCertificate_Id = ich.IdentityCertificate_Id
inner join BankDetailsHistories as bdh on fp.BankDetails_Id = bdh.BankDetails_Id
left join PacInsuranceDataHistories as pidh on fp.PacsInsuranceData_Id = pidh.PacsInsuranceData_Id
left join IncomeDetailsHistories as idh on fp.IncomeDetails_Id = idh.IncomeDetails_Id
where URN_No in(
select distinct MST_FarmerProfile_URN_No from PersonalDetailsHistories where MST_FarmerProfile_URN_No in(
select URN_No from MST_FarmerProfile where (CreatedOn>=#fromDate and CreatedOn<= #toDate and Status='Active')))
)a where a.num=1
Use this linq query after getting result from sql. p.ID is be your desire distinct column name
List<Person> distinctRecords = YourResultList
.GroupBy(p => new { p.ID})
.Select(g => g.First())
.ToList();

Resources