How can i convert this raw query to eloquent scope? - laravel

SELECT *
FROM employment_informations t1
WHERE NOT EXISTS (
SELECT 1 FROM employment_informations t2
WHERE t1.employee_id = t2.employee_id
AND t1.field_name = t2.field_name
AND t2.created_at > t1.created_at
)
This is what I have so far.
$builder->whereNotExists(function ($builder) {
$builder->select(\DB::raw(1))
->from('employment_informations t2')
->whereRaw('employment_informations.employee_id = t2.employee_id
AND employment_informations.field_name = t2.field_name
AND t2.created_at > employment_informations.created_at
');
});
I don't know how to alias table in eloquent scope.
here's the error:
[09:15:38] LOG.error: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'hris.employment_informations t2' doesn't exist (SQL: select count(*) as aggregate from `employment_informations` where not exists (select 1 from `employment_informations t2` where employee_id = t2.employee_id
AND field_name = t2.field_name
AND t2.created_at > created_at)) {"userId":1,"exception":{"errorInfo":["42S02",1146,"Table 'hris.employment_informations t2' doesn't exist"]}}
doesn't work using as either:
->from('employment_informations as t2')
If possible I want to alias the table with t1 and the subquery table to t2, but I don't know how to do it.

Laravel supports aliases on tables and columns with AS. Try
$query = DB::table('tablename AS t')->select('t.id AS uid')->get();

Related

How to join multiple table in Laravel?

I have 3 table
1- planes = name, description
2- presidents = id , p_name
3- plane_president = plane_id , president_id
how to join planes with presidents and plane_president?
$planes = Plane::join('plane_president', 'planes.id', '=', 'plane_president.plane_id')
->join('presidents', 'presidents.id', '=', 'plane_president.president_id');
error:
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in order clause is ambiguous (SQL: select * from `planes` inner join `plane_president` on `planes`.`id` = `plane_president`.`plane_id` inner join `presidents` on `presidents`.`id` = `plane_president`.`president_id` order by `id` asc limit 10 offset 0)
plane_president is a pivot table for president and planes, you can declare the relationship at the Plane.php model:
public function presidents()
{
return $this->belongsToMany(
President::class,
'plane_president',
'plane_id',
'president_id');
}
and use it like:
plane->presidents;
when you want to retrieve the presidents for a particular plane in a controller.
You have 2 columns named id as the error says it is ambiguous.
order by id asc limit 10 offset 0 here you aren't specifying by which column to order planes.id or presidents.id

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

Where Not In using query builder

Similary with this question I need to execute the following Sql query:
SELECT COUNT(*) from table where column NOT IN (SELECT table2.id from table2 where table2.someanothercolumn >0 );
Using Eloquent's query builder, therefore I tried the following (Model Table maps into table table and Model TableTwo maps into table table2):
$enties = Table::where('id',function($q){
$q->from('table2')->select('id')->where('someanothercolumn','>',0);
})->count();
But on the cide above how I can Place the NOT IN clause?
Your answer is in the following snippet of code:
$enties = Table::whereNotIn('id',function($q){
$q->from('table2')->select('id')->where('someanothercolumn','>',0);
})->count();
In other words just use the whereNotIn.

Oracle Invalid Identifier (with Inner Join)

I'm having an "Invalid Identifier" in Oracle because of the "B.username" (username column does exist in USER table). When i remove this, it's working fine. How to resolve this issue? I came from a MySQL background.
SELECT * FROM (SELECT qNA.assignment, qNA.regDate, B.username, (
SELECT DISTINCT NVL(idx, 0)
FROM EK_USERGRADE
WHERE year = (SELECT DISTINCT userGradeNo FROM EK_USER WHERE ID = qNA.userIdx)
) AS userGradeIdx
FROM EK_NEWTESTAPPLICANT qNA
WHERE IDX = :idx ) A
INNER JOIN EK_USER B ON (A.userIdx = B.ID)
Let's try this with a simplified version of your query:
-- test tables
create table NEWTESTAPPLICANT as select 1 useridx from dual ;
create table B as select 1 id, 'name1' username from dual ;
-- query
select *
from (
select B.username
from NEWTESTAPPLICANT qNA
) A join B on A.useridx = B.id ;
-- ORA-00904: "B"."USERNAME": invalid identifier
There's no "username" column in the NEWTESTAPPLICANT table, which causes the error. A LATERAL inline view (examples see here) may do the trick ...
-- query
select
*
from B, lateral (
select B.username
from NEWTESTAPPLICANT qNA
) A ;
-- result
ID USERNAME USERNAME
1 name1 name1
This works with Oracle 12c.
The problem is, that both your virtual table A and users B have the same column name "username". Specify alias in the main select, like "Select A.* , B.* from(...".
Is it ORA-00903?
User is a reserved word are you sure you created this table? Table name cannot be a reserved word.

SELECT within UPDATE gives an error

I am getting SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table error on this statement:
UPDATE
(
SELECT CELLS.NUM, UND.CLIENT_PARAMS
FROM CELLS
LEFT OUTER JOIN UND
ON CELLS.UND_ID = UND.ID
WHERE CELLS.SASE = 1
) t
SET t.CLIENT_PARAMS = 'test';
I would like to update CLIENT_PARAMS field for all rows, which select returns.
The most straightforward (though possibly not the most efficient) way to update rows in one table which correspond directly to rows in another table via an identity column would be to use WHERE table1.column IN (SELECT id FROM table2 WHERE ...).
In this case:
UPDATE UND
SET client_params = 'test'
WHERE id IN
(SELECT und_id
FROM CELLS
WHERE SASE=1)
Try this
UPDATE und u
SET client_params = 'test'
WHERE EXISTS
(SELECT 1
FROM cells c
WHERE C.SASE = 1
AND c.und_id = u.id)

Resources