How to convert SQL query to query builder? - laravel

controlens is a table in my database and entite, state are the fields of this table
SELECT a.entite, a.etat, COUNT(a.etat) as nombre_toperform, b.nombre_performed,c.nombre_incompatible
FROM `controlens` a
LEFT JOIN ( SELECT entite,COUNT(etat) as nombre_performed from `controlens` WHERE etat like 'PERFORMED' GROUP BY entite, etat) b on a.entite = b.entite
LEFT JOIN ( SELECT entite,COUNT(etat) as nombre_incompatible from `controlens` WHERE etat like 'INCOMPATIBLE' GROUP BY entite, etat) c on a.entite = c.entite
WHERE a.etat like '%TOPERFORM%'
GROUP BY a.entite, a.etat, b.nombre_performed,c.nombre_incompatible

There are likely few ways in which you can accomplish this. Here is one idea that might work (note: haven't fully tested, so it might need some tweaks):
$toPerform = '%TOPERFORM%';
$subQuery1 = 'SELECT entite,COUNT(etat) as nombre_performed from `controlens` WHERE etat like 'PERFORMED' GROUP BY entite, etat';
$subQuery2 = 'SELECT entite,COUNT(etat) as nombre_incompatible from `controlens` WHERE etat like 'INCOMPATIBLE' GROUP BY entite, etat';
DB::table('controlens as a')->select([
'a.entite',
'a.etat',
DB::raw('COUNT(a.etat) AS nombre_toperform'),
'b.nombre_performed',
'c.nombre_incompatible'
])
->leftJoin(DB::raw("($subQuery1) as b"), 'a.entite', '=', 'b.entite')
->leftJoin(DB::raw("($subQuery2) as c"), 'a.entite', '=', 'c.entite')
->where('a.etat', $toPerform)
->groupBy('a.entite', 'a.etat', 'b.nombre_performed', 'c.nombre_incompatible');
Alternatively, you could try this package to see if it helps the cause:
eloquent-subquery-magic
Beyond that, here are a few helpful articles that might point you in the correct direction:
subquery with join in
laravel
Laravel Fluent Query Builder Join with
subquery
How to write this (left join, subquery ) in Laravel
5.1?

Related

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']);

Laravel JOIN query with 2 conditions out of which one is NULL

I need a query where I want to join tables, on 2 conditions in OR. Out of these 2 condition is to check whether the column IS NULL.
$query->select('users.*', 'o.name', 'r.name')
->join('owners as o', 'users.owner_id', '=', 'o.id')
->join('residents as r', 'users.resident_id', '=', 'r.id');
In the above query I also want to check if the users.resident_id IS NULL i.e., users.resident_id = r.id OR users.resident_id IS NULL.
Thanks for your time and help in advance.
i haven't try this..
how about use "right join" sql..
from w3school..
SQL RIGHT JOIN Keyword. The RIGHT JOIN keyword returns all records from the right table (table2), and the matched records from the left table (table1). The result is NULL from the left side, when there is no match.
if this not working then use "whereIn"..
select all id with null data first, then select all id from join.. then you can use whereIn to select all data with id from data1 and data2..

laravel about inner join and subquery

ok, now ,I want get sql just like:
select field1,field2,field3 from orders
inner join
(select id from orders where field4=3 limit 1000, 20)
as temp using(id)
how can I get this by laravel 5.1?
er, sorry I poor in english. What I mean is I want get the native sql like that , and now I don't know what can I do with laravel DB or ORM. I create a model Order corresponding to the table orders.
thank you ~
Although it is not a good way to do it because laravel supports inner joins in query builder. You can do it like this:
DB::select(DB::raw(" select field1,field2,field3 from orders
inner join
(select id from orders where field4=3 limit 1000, 20)
as temp using(id)
"))->get();
Use the following code
DB::select(DB::raw(" select field1,field2,field3 from orders
inner join
(select id from orders where field4=3 limit 1000, 20)
as temp using(id)
"))->get();

Converting a raw query to Laravel query builder

I have the following MySQL query which fetches a list of the last 9 authors to write a post and lists them in order of the date of the last post they wrote.
It's working properly but I'd like to re-write it using the Laravel Query Builder. Here is the query at the moment:
$authors = DB::select("
SELECT
`a`.`id`,
`a`.`name`,
`a`.`avatar`,
`a`.`slug` AS `author_slug`,
`p`.`subheading`,
`p`.`title`,
`p`.`slug` AS `post_slug`,
`p`.`summary`,
`p`.`published_at`
FROM
`authors` AS `a`
JOIN
`posts` AS `p`
ON `p`.`id` =
(
SELECT `p2`.`id`
FROM `posts` AS `p2`
WHERE `p2`.`author_id` = `a`.`id`
ORDER BY `p2`.`published_at` DESC
LIMIT 1
)
WHERE
`a`.`online` = 1
ORDER BY
`published_at` DESC
LIMIT 9
");
I understand the basics of using the query builder, but there doesn't appear to be anything in the Laravel docs that allows for me to JOIN a table ON a SELECT.
Can anyone suggest a way that I can write this query using the Laravel Query builder, or perhaps suggest a way that I can rewrite this query to make it easier to structure with the query builder?
Try to do like this
$data = DB::table('authors')
->select(
'a.id',
'a.name',
'a.avatar',
'a.slug AS author_slug',
'p.subheading',
'p.title',
'p.slug AS post_slug',
'p.summary',
p.published_at')
->from('authors AS a')
->join('posts AS p', 'p.id', '=', DB::raw("
(
SELECT p2.id FROM posts AS p2
WHERE p2.author_id = b.id
ORDER BY p2.published_at
DESC LIMIT 1
)"))
->where('a.online', 1)
->limit(9)
->orderBy('p.published_at', 'desc')
->get();

Informatica Powercenter Add Select LISTAGG query

I have learning informatica powercenter. I was able to do an INNER JOIN between two VIEWs. I added the INNER JOIN in the User Defined Join but still have to make correct changes in the Sql Query when click on Validate. Do I just need to only add to User Defined Join when I am joining VIEWS?
Here is my problem. I got another VIEWs which is one to many, so this will be my 3rd VIEW to add to the query. I got this running on TOAD. How do I add this to Infromatica? Do I just avoid the Sql Query section and add the entire query into User Defined Query? Do LISTAGG works in Informatica?
If not in the Query for LISTAGG (one-many relationship), is it better or is there a way to do this in the transformation like expression transformation?
Thanks.
This query is a SELECT, LISTAGG, CASE
SELECT PERSON_ID,
FIRST_NAME,
MIDDLE_NAME,
LAST_NAME,
LISTAGG(val,',') WITHIN GROUP (ORDER BY Table2.SKILL_SHORT_DESC )
FROM (SELECT DISTINCT Table1.PERSON_ID,
Table1.FIRST_NAME,
Table1.MIDDLE_NAME,
Table1.LAST_NAME,
(case
when Table2.SKILL_SHORT_DESC = '1' then '1:1'
when Table2.SKILL_SHORT_DESC = '2' then '2:2'
when Table2.SKILL_SHORT_DESC = '3' then '3:3'
when Table2.SKILL_SHORT_DESC = '4' then '4:4'
when Table2.SKILL_SHORT_DESC = '5' then '5:5'
when Table2.SKILL_SHORT_DESC = '6' then '6:6'
when Table2.SKILL_SHORT_DESC = '7' then '7:7'
when Table2.SKILL_SHORT_DESC = '8' then '8:8'
when Table2.SKILL_SHORT_DESC = '9' then '9:9'
else ''
end) as val
FROM Table1
LEFT JOIN Table2
ON Table2.PERSON_ID = Table1.PERSON_ID
)
GROUP BY PERSON_ID,FIRST_NAME,MIDDLE_NAME, LAST_NAME
Yes, LISTAGG should work. Assuming you are using oracle, it should work 10.x and higher version. Frankly, Informatica doesn't care what you write as SQL but its the database where SQL is being issued matters. You can write 'I am batman' and infa will return, 'Invalid syntax'.
Koushik
Please follow below steps,
Get any dummy source from the table
In source qualifier, remove all the ports and create the ports you required
In properties --> Sql query, add the query you have created. No need to provide any user defined joins
Below are the screen shots for better understanding.

Resources