How to convert sql to hql with join and max - mysql

I am trying to make this query in hql so i don't have to mapper the query result into my java object , but after trying different options, i still can't make it work. Is it possible to perform this query in hql in any way? The query is:
select t.*
from part_movement t
join
( select id_block_movement, max(start_date) as somedate
from part_movement
where id_area_final_destination = 1
and ((id_area_destination != id_area_final_destination and id_user_receiver is not null) or
(id_area_destination = id_area_final_destination and id_user_receiver is null))
group by id_block_movement
) s
on s.id_block_movement = t.id_block_movement
and s.somedate= t.start_date;

ok i got it finally!! It was: (feels wired answearing myself without having any answear from someone else )
Query q2 = s.createQuery(" from PartMovement t "
+ " WHERE t.areaByIdAreaFinalDestination = ? "
+ " AND t.startDate IN (select max(b.startDate) from PartMovement b "
+ " WHERE ((b.areaByIdAreaDestination != b.areaByIdAreaFinalDestination and b.usersByIdUserReceiver is not null) OR "
+ " (b.areaByIdAreaDestination = b.areaByIdAreaFinalDestination and b.usersByIdUserReceiver is null)) "
+ " group by b.idBlockMovement )");

Related

How to do SUM(MAX( ) + MAX( ))?

Is there a proper way to do SUM(MAX() + MAX())?
Here's what I've been trying to do
SELECT
SUM(MAX(account.BALANCE1) + MAX(account.BALANCE2)) AS TOTALBALANCE
FROM
account
JOIN
transaction t ON account.PRIMARYKEY = t.ACCOUNTKEY
WHERE
NOT EXISTS( SELECT
1
FROM
transaction a
WHERE
a.ACCOUNTKEY = t.ACCOUNTKEY
AND a.TYPE = 'PAYMENT')
HAVING TOTALBALANCE > 0
It reads:
Error Code: 1111. Invalid use of group function
Since you don't have any GROUP BY clause specified,
MAX(account.BALANCE1) + MAX(account.BALANCE2)
should aready suffice your needs.

getting error from mysqli_fetch_array

My query line is:
SELECT TR.*,
PL.*, DE.*,
( DE.power + DE.stamina + DE.violence + DE.speed + DE.shooting + DE.scoring + DE.pass + DE.ball_control + DE.talent ) AS TPOWER,
strftime('%Y-%d-%m', DE.age, 'unixepoch') AS age
FROM `transfers` TR JOIN `players` PL ON TR.player_id=PL.id
JOIN `playerdetails` DE ON TR.player_id=DE.player_id
WHERE PL.position = 'MD' AND ( age >= '20' AND age <= '24' )
AND PL.firstname = 'a' AND PL.lastname = 'b' AND TPOWER >= '1'
AND TPOWER <= '5' AND TR.price >= '20' AND TR.price <= '50'
ORDER BY age DESC
What's wrong with this query?
An error occurred:
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in E:\EasyPHP-Devserver-16.1\eds-www\classes\DB.php on line 15
MySQL doesn't have a function called strftime(). You might want date_format() instead:
SELECT . . .
date_format(de.age, '%Y-%d-%m') AS age
However, that seems like a strange way to express the age (which is usually an integer, number, or interval).
Your query could have other errors as well. You should check the error messages that are returned.

Alternate to ORDER BY subquery

From the database at http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_orderby2, for example (Click "Run SQL"), I want to list the customer who has the largest CustomerID that is greater than 80 first among a list of all customers from USA. So I use
SELECT * FROM Customers
WHERE Country = 'USA'
ORDER BY CustomerID = (SELECT MAX(CustomerID) FROM Customers
WHERE CustomerID > 80 AND Country = 'USA') DESC, PostalCode;
but this is not the real query I'm using. If the SELECT... FROM... WHERE... portion of the query is more complex, what is a more elegant query?
The actual query I am trying to modify is
SELECT post.postid, post.visible, post.userid, post.parentid, post.vote_count
FROM " . TABLE_PREFIX . "post AS post
WHERE post.threadid = $threadid
AND post.visible IN (1" . (!empty($deljoin) ? ", 2" : "") .
($show['approvepost'] ? ", 0" : "") . ")
ORDER BY post.postid = {$threadinfo['firstpostid']} DESC, post.vote_count > 5 DESC,
post.dateline $postorder
where the post.vote_count > 5 DESC portion I am trying to replace with only the largest post.vote_count that is larger than 5. So I use:
SELECT post.postid, post.visible, post.userid, post.parentid, post.vote_count
FROM " . TABLE_PREFIX . "post AS post
WHERE post.threadid = $threadid
AND post.visible IN (1" . (!empty($deljoin) ? ", 2" : "") .
($show['approvepost'] ? ", 0" : "") . ")
ORDER BY post.postid = {$threadinfo['firstpostid']} DESC, post.vote_count = (
SELECT MAX(post.vote_count)
FROM " . TABLE_PREFIX . "post AS post
WHERE post.threadid = $threadid
AND post.visible IN (1" . (!empty($deljoin) ? ", 2" : "") .
($show['approvepost'] ? ", 0" : "") . ")
AND post.vote_count > 5
)
DESC, post.dateline $postorder
and all is good. But you can imagine a more complex query, perhaps with INNER JOIN, whose SELECT... FROM... WHERE... etc. must all be duplicated in the subquery.
So my question is, I suspect, can you order query results so the first item (within those results) has the maximum of a field, and the remainder ordered otherwise, without essentially rewriting the entire query in a subquery?
MySQL does not support CTE's, which would have been the perfect solution to simplify your query. They can be emulated with a view though :
CREATE VIEW c AS (SELECT Customer.* FROM Customer WHERE Country = "USA");
SELECT c.* FROM c ORDER BY CustomerID = (SELECT MAX(CustomerID) FROM c) DESC;
DROP VIEW c;
In your case, this would give :
CREATE VIEW p AS (
SELECT post.postid, post.visible, post.userid, post.parentid, post.vote_count
FROM " . TABLE_PREFIX . "post AS post
WHERE post.threadid = $threadid
AND post.visible IN (1" . (!empty($deljoin) ? ", 2" : "") .
($show['approvepost'] ? ", 0" : "") . ")
);
SELECT p.* FROM p
ORDER BY p.postid = {$threadinfo['firstpostid']} DESC, p.vote_count = (
SELECT MAX(p.vote_count)
FROM p
WHERE p.vote_count > 5
)
DESC, post.dateline $postorder;
DROP VIEW p;
This query will list data in descending order of CustomerID
SELECT * FROM Customers
WHERE Country = 'USA'
ORDER BY CustomerID DESC, PostalCode;

MySQL procedure - how to improve performance of query?

I have MySQL procedure which is collecting data from 3 tables:
dossier
courrier
courrier_concerne_dossier
Simply I just can't use select * from... I need every dossier_str separated (one dossier_str in each column and all in one big result set).
(SELECT dossier_oid from data.courrier_concerne_dossier where courrier_oid = param_oid LIMIT 1) as 'dossier1_oid',
(SELECT concat(a.prefixe_numero, "-", cast(a.numero as char), " - ",DATE_FORMAT(a.date_ouverture, '%e/%c/%Y'), " - ", b.nom, " - ", a.intitule)
FROM data.dossier as a
JOIN data.client as b on
a.client_oid=b.oid
WHERE a.oid = dossier1_oid) as 'dossier1_str',
(SELECT dossier_oid from data.courrier_concerne_dossier where courrier_oid = param_oid LIMIT 1,1) as 'dossier2_oid',
(SELECT concat(a.prefixe_numero, "-", cast(a.numero as char), " - ",DATE_FORMAT(a.date_ouverture, '%e/%c/%Y'), " - ", b.nom, " - ", a.intitule)
FROM data.dossier as a
JOIN data.client as b on
a.client_oid=b.oid
WHERE a.oid = dossier2_oid) as 'dossier2_str',
(SELECT dossier_oid from data.courrier_concerne_dossier where courrier_oid = param_oid LIMIT 2,1) as 'dossier3_oid',
(SELECT concat(a.prefixe_numero, "-", cast(a.numero as char), " - ",DATE_FORMAT(a.date_ouverture, '%e/%c/%Y'), " - ", b.nom, " - ", a.intitule)
FROM data.dossier as a
JOIN data.client as b on
a.client_oid=b.oid
WHERE a.oid = dossier3_oid) as 'dossier3_str',

how to use limit keyword in oracle

I am retrieving data from table but instead of all row, I want 20 rows at a time for pagination. For this I use limit keyword which work perfectly in Mysql but not in Oracle.
Code:
"select "+ "C.CONTRACTOR_ID,C.CONTRACTOR_NAME,nvl(C.CONTACT_PERSON_1,'-'),nvl(C.CONTACT_PERSON_2,'-'),C.REGISTRATION_NO,CRA.DESCRIPTION REG_AUTH_NAME,"+
"to_char(C.VALID_FROM,'dd/mm/yyyy'),to_char(C.VALID_TO,'dd/mm/yyyy'),CC.DESCRIPTION CONTRACTOR_CLASS,C.INCORP_PLACE,"+
"IT.DESCRIPTION INCORP_TYPE,nvl(to_char(C.DATE_OF_INCORP,'dd/mm/yyyy'),'-') DATE_OF_INCORP,C.ADDRESS1,nvl(C.ADDRESS2,'-'),nvl(C.EMAIL_ID,'-'),"+
"nvl(C.WEBSITE_URL,'-'),nvl(C.PHONE_NO,'-'),nvl(C.FAX_NO,'-'),nvl(C.MOBILE_NO,'-'),C.BANK_NAME,C.BANK_BRANCH,C.ACCOUNT_NO,C.IFSC_CODE," +
"C.PAN_NO,nvl(C.TIN_NO,'-'),nvl(C.CST_NO,'-') "+
"from "+
"CONTRACTOR C "+
"inner join CONTRACTOR_REG_AUTH CRA on CRA.REG_AUTH_ID=C.REG_AUTH_ID "+
"inner join CONTRACTOR_CLASS CC on CC.CLASS_ID=C.CONTRACTOR_CLASS_ID "+
"inner join INCORPORATION_TYPE IT on IT.INCORP_TYPE=C.INCORP_TYPE "+
"limit " + offset + ", " + noOfRecords ";
Here no order by keyword is there. I am retrieving data from different table and then display only 20 rows at a time.
In Oracle, you can use the special rownum variable. This example behaves like limit FirstRow, NrOfRows:
select *
from (
select *
, rownum as rn
from YourTable
order by
id
) as SubQueryAlias
where FirstRow <= rn
and rn < FirstRow + NrOfRows
An optimized version of this query from AskTom, linked from this SO question:
select *
from (
select /*+ FIRST_ROWS(n) */
rownum as rn
, *
from (
select *
from YourTable
order by
id
) as SubQueryAlias1
where rownum <= FirstRow + NrOfRows
) as SubQueryAlias2
where rn >= FirstRow