how i can manipulate nested query j2ee hibernate - mysql

I have the following query, the problem that hibernate does not support nested after the 'from' I tried to create a view, but it did not work, I want to know how can I use hibernate to run this query correctly
SELECT sum(dc.nbrDefaut) def, a.nb control,c.id_of
FROM controlequalite c ,detailscontrole dc,
(select sum(nbreControlle) nb, id_monitrice
from controlequalite group by id_monitrice) a
where c.id = dc.id_controle
and c.id_monitrice = a.id_monitrice
and c.date >= '2016-03-25 00:00:00'
group by c.id_monitrice,c.id_of;

With a query like this, the simplest way is to use a native query. I'm assuming you are using JPA/Hibernate as ORM, so you can simply do like:
List<YourObject> resultList = yourEntityManager.createNativeQuery("nativeSQLhere", YourObject.class).getResultList();

Related

Writing Complex SQL Queries Using Spring Specificaitons

I'm having a complex SQL query which I want to execute in my Spring boot application. Following is a part of it's JPQL equivalent:
SELECT j FROM Job j WHERE
( (?6 = 0L) OR
0L IN (SELECT i12.filterFieldId FROM IjpPublishFilterFields i12 WHERE i12.jobId = j.id AND i12.fieldType LIKE 'GRADE') OR
(?6 IN (SELECT node.id FROM Grade node
INNER JOIN Grade parent ON ((node.lft BETWEEN parent.lft AND parent.rgt) AND
parent.id IN (SELECT i1.filterFieldId FROM IjpPublishFilterFields i1 WHERE **j.id** = i1.jobId AND i1.fieldType LIKE 'GRADE'))
WHERE node.organizationId = ?5 AND
node.isActive = true AND
parent.isActive = true )))
Since there are multiple other conditions which require to form 'Where' clause dynamically, I believe #Query annotation is out of the window.
After a lot of research, still I'm unable to convert this where clause to Specification.
e.g., I can return whole IjpPublishFilterFields object but can't return just i12.filterFieldId.
How could I write the where clause using JPA Specification?
I was able to solve this by using EnitityManager.createQuery() and formed this equivalent JPQL using simple String concatenation. Still I believe, we should be able to form this where caluse using Spring data JPA Specifications. So, further hints are welcomed.
There is nothing special about your query, so you should be able to translate this to something like criteriaBuilder.or( criteriaBuilder.eq(param, 0L), criteriaBuilder.literal(0L).in(subquery1), param.in(subquery2) ) where subquery1 and subquery2 are constructed roughly like this: Subquery<Long> subquery1 = criteriaQuery.subquery(Long.class); Root<IjpPublishFilterFields> r = subquery1.from(IjpPublishFilterFields.class); subquery1.select(r.get("filterFieldId")); ...

How to use pagination on DB::select(query) - Laravel

i have some query and i just know how to query on mysql (phpmyadmin)
i got information if using DB::select we cannot to use paginate, so we need change to DB::table(some query) to using pagination.
but the problem is i am confuse how to convert my query into DB::table(some query)
Here is my code
$daily = DB::select("
SELECT
employees.employee_name,
COUNT(DISTINCT DATE(attendance.attendance_datetime)) as jumlah,
locations.location_name,
TIME(MIN(attendance.attendance_datetime)) as check_in,
CASE
WHEN ISNULL(TIME(MIN(attendance.attendance_datetime))) THEN attendance_absence.remarks
WHEN TIME(MIN(attendance.attendance_datetime)) > '08:05:00' THEN (SELECT TIMEDIFF('08:05:00', MIN(TIME(attendance_datetime))))
WHEN TIME(MIN(attendance.attendance_datetime)) <= '08:05:00' THEN 'Good'
ELSE 'No Record'
END as detail_telat,
attendance_absence.remarks as remarks
FROM
employees
LEFT JOIN attendance ON employees.employee_name = attendance.attendance_name AND DATE(attendance.attendance_datetime) = '$date'
LEFT JOIN locations ON employees.location_id = locations.id
LEFT JOIN attendance_absence ON attendance_absence.employee_name = employees.employee_name AND attendance_absence.absences_date = '$date'
WHERE locations.location_name LIKE '%'
GROUP BY employees.employee_name
ORDER BY employees.employee_name
")->paginate(3);
please help me to convert my query into eloquent or query builder, or any suggestion ?
Currently, pagination operations that use a groupBy statement cannot be executed efficiently by Laravel. If you need to use a groupBy with a paginated result set, it is recommended that you query the database and create a paginator manually.
Check documentation

Doctrine 2 does not recognize SELECT on the FROM clause

I have a SQL query I would like to use in Doctrine2.
My query, goes to the dabatase, does a GROUP BY user state and COUNT the number of users per state.
Then I'm trying to join a table to COUNT all users and make a percent for every state.
return $this->getEntityManager()
->createQuery("
SELECT COUNT(u.id) as total,
(100*(COUNT( u.id ) / total_users.total)) as percent
FROM UserBundle:User u,
(SELECT COUNT(*) as total
FROM UserBundle:User) as total_users
LEFT JOIN u.idUserEstado ue
GROUP BY u.idUserEstado")
->getResult();
The problem is, when I run the Doctrine2 query I get an exception:
[Semantical Error] line 0, col 397 near
'(SELECT COUNT(': Error: Class '(' is not defined.
Doctrine does not recognize that SELECT on the FROM clause.
Select on the from clause are not handled by doctrine 2
There is a closed (and not accepted) feature request on doctrine's jira : http://www.doctrine-project.org/jira/browse/DDC-2793
DQL is about querying objects. Supporting subselects in the FROM
clause means that the DQL parser is not able to build the result set
mapping anymore (as the fields returned by the subquery may not match
the object anymore). This is why it cannot be supported (supporting it
only for the case you run the query without the hydration is a no-go
IMO as it would mean that the query parsing needs to be dependant of
the execution mode).
(SELECT COUNT( * ) as total FROM UserBundle:User) as total_users
COUNT(*) may not exists in DQL. Try COUNT(u.id), the results will be the same. You also have the possibility to try this in an EntityRepository :
$qb->select(array(
'count(u.id) as total',
'(100*(count(u.id)/total_users.total)) as percent',
'select count(u.id) as total_users) as total_users'))
->from('UserBundle:User')
->leftJoin('u.idUserEstado','ue')
->groupBy('u.idUserEstado');
return $qb->getQuery()->getResult();
Source: Google UserGroup issue
the
... FROM UserBundle:User u, ...
is strange. Maybe it can't find the class User.

Why is Linq2SQL generating a nested query instead of using a JOIN?

I'm trying to understand why Linq is generating the SQL that it is for the statement below:
var dlo = new DataLoadOptions();
dlo.LoadWith<TemplateNode>(x => x.TemplateElement);
db.LoadOptions = dlo;
var data = from node in db.TemplateNodes
where node.TemplateId == someValue
orderby node.Left
select node;
Which generates the following SQL:
SELECT [t2].[Id],
[t2].[ParentId],
[t2].[TemplateId],
[t2].[ElementId],
[t2].[Left] AS [Left],
[t2].[Right] AS [Right],
[t2].[Id2],
[t2].[Content]
FROM (SELECT ROW_NUMBER() OVER (ORDER BY [t0].[Left]) AS [ROW_NUMBER],
[t0].[Id],
[t0].[ParentId],
[t0].[TemplateId],
[t0].[ElementId],
[t0].[Left],
[t0].[Right],
[t1].[Id] AS [Id2],
[t1].[Content]
FROM [dbo].[TemplateNode] AS [t0]
INNER JOIN [dbo].[TemplateElement] AS [t1]
ON [t1].[Id] = [t0].[ElementId]
WHERE [t0].[TemplateId] = 16 /* #p0 */) AS [t2]
WHERE [t2].[ROW_NUMBER] > 1 /* #p1 */
ORDER BY [t2].[ROW_NUMBER]
There is a Foreign Key from TemplateNode.ElementId to TemplateElement.Id.
I would have expected the query to produce a JOIN, like so:
SELECT * FROM TemplateNode
INNER JOIN TemplateElement ON TemplateNode.ElementId = TemplateElement.Id
WHERE TemplateNode.TemplateId = #TemplateId
As per the suggestions in the answers to this question I have profiled both queries and the JOIN is 3 times faster than the nested query.
I'm using a .NET 4.0 Windows Forms app to test with SQL Server 2008 SP2 64bit developer edition.
The only reason that LINQ-SQL would generate the ROW_NUMBER query is due to the Skip Method. As bizare as the above SQL seems, I think within T-SQL there is no construct for simple paging like MySQL's Limit 10,25, so you get the above SQL when using Skip and Take.
I would assume that there is a Skip being used for paging purposes and LINQ-SQL is modifying the query. If you use an application like LINQ-Pad you can run different LINQ queries to see their generated SQL.
Your example of a join is not equivalent. You cannot get the ROW_NUMBER and subsequently select only rows WHERE ROW_NUMBER > 1 with a simple join. You would have to do a sub-select or similar to get this result.

Doctrine issue - Different queries, same results but not with Doctrine

i'm having a little issue with doctrine using symfony 1.4 (I think it's using doctrine 1.2). I have 2 queries, using raw sql in the mysql console, they produce the same resultset. The queries can be generated using this code :
$dates = Doctrine::getTable('Picture')
->createQuery('a')
->select('substr(a.created_at,1,10) as date')
->leftjoin('a.PictureTag pt ON a.id = pt.picture_id')
->leftjoin('pt.Tag t ON t.id = pt.tag_id')
->where('a.created_at <= ?', date('Y-m-d 23:59:59'))
->orderBy('date DESC')
->groupby('date')
->limit(ITEMS_PER_PAGE)
->offset(ITEMS_PER_PAGE * $this->page)
->execute();
If I remove the two joins, it changes the query, but the resultset it's the same.
But using doctrine execute(), one produces only one row.
Somebody have an idea on what's going on here?
PS : Picture table has id, title, file, created_at (format 'Y-m-d h:i:s'), the Tag table is id, name and PictureTag is an relationship table with id and the two foreign keys.
PS 2 : Here are the two sql queries produced (the first without joins)
SELECT substr(l.created_at, 1, 10) AS l__0 FROM lupa_picture l WHERE (l.created_at <= '2010-03-19 23:59:59') GROUP BY l__0 ORDER BY l__0 DESC LIMIT 4
SELECT substr(l.created_at, 1, 10) AS l__0 FROM lupa_picture l LEFT JOIN lupa_picture_tag l2 ON (l.id = l2.picture_id) LEFT JOIN lupa_tag l3 ON (l3.id = l2.tag_id) WHERE (l.created_at <= '2010-03-19 23:59:59') GROUP BY l__0 ORDER BY l__0 DESC LIMIT 4
I had something similar this week. Doctrine's generated SQL (from the Symfony debug toolbar) worked fine in phpMyAdmin, but failed when running the query as in your question. Try adding in the following into your query:
->setHydrationMode(Doctrine::HYDRATE_SCALAR)
and see if it gives you the expected result. If so, it's down to the Doctrine_Collection using the Picture primary key as the index in the collection. If you have more than 1 result with the same index, Doctrine will refuse to add it into the collection, so you only end up with 1 result. I ended up running the query using a different table rather than the one I wanted, which resulted in a unique primary key and then the results I wanted appeared.
Well, the solution was that...besides substr(), it needs another column of the table. Using select(substr(), a.created_at) made it work