How to convert a SQL query to a Laravel DB query? - database

I have an SQL query.
SELECT
nguyenlieu.manguyenlieu,
nguyenlieu.tennguyenlieu,
SUM(chitietnhapmua.soluong) AS slsum
FROM chitietnhapmua
JOIN nguyenlieu
ON nguyenlieu.manguyenlieu = chitietnhapmua.manguyenlieu
JOIN
(SELECT nhapmua.* FROM nhapmua WHERE nhapmua.trangthai = 1) AS nhapmua
ON nhapmua.maphieunhap = chitietnhapmua.maphieunhap
GROUP BY nguyenlieu.manguyenlieu
It run on the SQL. I have to try
$data = DB::table('nguyenlieu')
->join('chitietnhapmua','nguyenlieu.manguyenlieu','=','chitietnhapmua.manguyenlieu')
->join('nhapmua',function($join){
$join->on('nhapmua.maphieu','=','chitietnhapmua.maphieu')
->where('nhapmua.trangthai','=','1');
})
->select('nhapmua.maphieunhap','nguyenlieu.manguyenlieu','nguyenlieu.tennguyenlieu','chitietnhapmua.soluong')
->get();
but I can't to translate to Laravel framework using class DB.

Related

Write an aggregate function

Can we write an aggregate function for my SQL script.? As I expect that I can make a function as string_agg of SQL Server.
Select e.EmployeeId, MyAggregateFunction(e.Task, ', ')
From EmployeeTask as e
Group by e.EmployeeId
I know I can use string_agg. But I want to write it myself to use it in entity framework. Entity Framework cannot translate into string_agg.
This is my code in Entity Framework:
var result = _context.EmployeeTask.FindAsQueryable().GroupBy(x => x.EmployeeId).Select(x => new {EmployeeId = x.Key, Tasks = DbFunction.MyAggregateFunction(x => x.Task)});
I don't want to use .AsEnumrable() before GroupBy().

How to add and delete linkedserver in SQL Server in runtime using Vb.net

I use update and insert query using joint tables in two different SQL Servers using linked server. But I don't like my remote server link open to users in SQL Server Management Studio. Instead I would like to create an delete the linked server at runtime. Is this possible using VB.net?
UPDATE Category
SET Category.HQID = B.[ID],
Category.DepartmentID = B.[departmentid],
Category.Name = B.[name],
Category.Code = B.[code],
Category.LastUpdated = B.[lastupdated]
FROM
Category A
INNER JOIN
[Myremoteserver].[MyRemoteDatabase].[dbo].[Category] B ON A.HQID = B.ID
WHERE
A.HQID <> B.ID
OR A.DepartmentID <> B.departmentID
OR A.Name <> B.name
OR A.Code <> B.code
OR A.LastUpdated <> B.lastupdated
Thanks in advance

Using FOR XML to return child queries

I am doing the subquery below as a parameter in a SELECT statement in SQL Server 2008. Is there any disadvantage of doing this to get a child query of the parent and parse it out on the server when its returned. Seems to easy.
(
SELECT ag.Name, ag.[Description], ega.Gender, ag.[Order], ag.[Type]
FROM GrassrootsHoops.EventAgeGrade ega
INNER JOIN GrassrootsHoops.AgeGrade ag ON ega.AgeGradeId = ag.Id
WHERE ega.EventId = ev.Id FOR XML PATH('AgeGrade'), ROOT('AgeGrades')
) AS AgeGrades

Doctrine Query Builder not working with UPDATE and INNER JOIN

In my repository I have this query:
$qb = $this->getEntityManager()->createQueryBuilder();
$qb
->update('MyBundle:Entity1', 'e1')
->join('e1.Entity2', 'e2')
->set('e1.visibile', '1')
->andWhere('e2.id = :id')->setParameter("id", 123)
;
throw this error
[Semantical Error] line 0, col 66 near 'e2.id = :id': Error: 'e2' is not defined
I have checked the relation and it is right.
Is there any issue using join in query update?
You can not use join on update and delete queries. You have to use subqueries.
Joins are not supported on update and delete queries because it is not
supported on all dbms. It won't be implemented in Doctrine 1 or
Doctrine 2. You can however get the same affect by using subqueries.
http://www.doctrine-project.org/jira/browse/DC-646
If you are using MySQL, using subqueries will not work. You will have then to use 2 queries.
In MySQL, you cannot modify a table and select from the same table in
a subquery
http://dev.mysql.com/doc/refman/5.0/en/subqueries.html
Doctrine DQL does not support join in update.
Try doing the following :
$qb = $this->getEntityManager()->createQueryBuilder();
$qb
->update('MyBundle:Entity1', 'e1')
->set('e1.visibile', '1')
->where('e1.Entity2 = :id')
->setParameter("id", 123)
;
You can set the id, as long as it is the primary key, of the linked entity directly as if it was the entity, Doctrine will map it.
I'm doing the exact same thing in my queries and it works.
try using a subquery instead Join will not work in DQL while you re doing an update:
LEFT JOIN, or JOINs in particular are only supported in UPDATE
statements of MySQL. DQL abstracts a subset of common ansi sql, so
this is not possible. Try with a subselect:
$qb = $this->getEntityManager()->createQueryBuilder();
$qb ->update('MyBundle:Entity1', 'e')
->set('e.visibile', '1')
->where('e.id IN (SELECT e1.id FROM Entity1 e1 INNER JOIN e2.Entity2 e2 WHERE e2 = :id')
->setParameter("id", 123);
Very old question, but do not contain an answer in full query builder.
So yes, the following query is not possible to sync fields of two tables:
$this->createQueryBuilder('v')
->update()
->join(Pegass::class, 'p', Join::WITH, 'v.identifier = p.identifier')
->set('v.enabled', 'p.enabled')
->where('p.type = :type')
->setParameter('type', Pegass::TYPE_VOLUNTEER)
->andWhere('v.enabled <> p.enabled');
The generated query do not contain the relation because of its lack of support in all dbms as explained above. They also tell you to use subqueries instead.
So that's how I did the equivalent (even if using 2 queries and is less performant...):
foreach ([false, true] as $enabled) {
$qb = $this->createQueryBuilder('v');
$sub = $this->_em->createQueryBuilder()
->select('p.identifier')
->from(Pegass::class, 'p')
->where('p.type = :type')
->andWhere('p.enabled = :enabled');
$qb
->setParameter('type', Pegass::TYPE_VOLUNTEER)
->setParameter('enabled', $enabled);
$qb
->update()
->set('v.enabled', $enabled)
->where($qb->expr()->in('v.identifier', $sub->getDQL()))
->getQuery()
->execute();
}

Convert this SQL Query to LINQ Query

I need to convert this SQL Query to LINQ Query, also I need to expose the SQL Select properties:
SELECT Problem.ProblemID, ProblemFactory.ObjectiveID, Objective.Name, ProblemFactory.Time, ProblemType.ProblemTypeName, ProblemFactory.OperationID,
ProblemFactory.Range1ID, ProblemFactory.Range2ID, ProblemFactory.Range3ID, ProblemFactory.Range4ID,
ProblemFactory.MissingNumber
FROM Problem INNER JOIN ProblemFactory ON Problem.ProblemFactoryID = ProblemFactory.ProblemFactoryID
INNER JOIN ProblemType ON ProblemFactory.ProblemTypeID = ProblemType.ProblemTypeID
INNER JOIN Objective ON Objective.ObjectiveID = ProblemFactory.ObjectiveID
UPDATE 1:
This is what I have:
var query = from problem in dc.Problem2s
from factory
in dc.ProblemFactories
.Where(v => v.ProblemFactoryID == problem.ProblemFactoryID)
.DefaultIfEmpty()
from ...
And I'm using this example: What is the syntax for an inner join in LINQ to SQL?
Something like this?
var query =
from p in ctx.Problem
join pf in ctx.ProblemFactory on p.ProblemFactoryID equals pf.ProblemFactoryID
join pt in ctx.ProblemType on pf.ProblemTypeID equals pt.ProblemTypeID
join o in ctx.Objective on pf.ObjectiveID equals o.ObjectiveID
select new
{
p.ProblemID,
pf.ObjectiveID,
o.Name,
pf.Time,
pt.ProblemTypeName,
pf.OperationID,
pf.Range1ID,
pf.Range2ID,
pf.Range3ID,
pf.Range4ID,
pf.MissingNumber,
};
But what do you mean by the "SQL Select properties"?
One of the benefits of an ORM like Linq-to-SQL is that we don't have to flatten our data to retrieve it from the database. If you map your objects in the designer (i.e. if you have their relationships mapped), you should be able to retrieve just the Problems and then get their associated properties as required...
var problems = from problem in dc.Problem2s select problem;
foreach (var problem in problems)
{
// you can work with the problem, its objective, and its problem type.
problem.DoThings();
var objective = problem.Objective;
var type = problem.ProblemType;
}
Thus you retain a logical data structure in your data layer, rather than anonymous types that can't easily be passed around.

Resources