How to add join subqueries - mysql

I have following sql query that I'm trying to add to JPA repository
SELECT 1
FROM recipient r
INNER JOIN (
SELECT m.id, MAX(m.created_at)
FROM message m INNER JOIN thread t
ON t.id = m.thread_id
WHERE t.id=19
) th
ON th.id = r.message_id
WHERE r.recipient_id = 12
I converted the query as follows
#Repository
public interface RecipientJpaRepository extends JpaRepository<RecipientModel, Long> {
#Query(
"SELECT 1 \n"+
"FROM RecipientModel r \n"+
"INNER JOIN ( \n"+
" SELECT m.id, MAX(m.createdAt) \n"+
" FROM MessageModel m INNER JOIN ThreadModel t \n"+
" ON t.id = m.threadId \n"+
" WHERE t.id=19 \n"+
") th \n"+
"ON th.id = r.messageId \n"+
"WHERE r.recipientId = 12 "
)
int isRecipientOfThread();
}
When running, application stops due to syntax error near ( bracket of the inner join.
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 3, column 12 [SELECT 1
INNER JOIN (
SELECT m.id, MAX(m.createdAt)
FROM fi.mediconsult.omasagamicroservicemessage.model.MessageModel m INNER JOIN fi.mediconsult.omasagamicroservicemessage.model.ThreadModel t
ON t.id = m.threadId
WHERE t.id=19
How can I add a query as the inner join?

SubQueries in from clause are not allowed in JPA and HQL.
These are the available possibilities.
https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/queryhql-subqueries.html

Related

Commands out of sync; you can't run this now

I'm doing a query on mysql with a subquery in the SELECT clause and I got this error: #2014 - Commands out of sync; you can't run this command now
I haven't been able to solve it. Can you help me please?
SELECT e.IdDocumento, e.CveDistrito, d.STCT_NOM, e.CveJuzgado, j.CTJU_DESCR, e.NumDocumento, e.IdRamoDocumento, r.Descripcion....., (SELECT pd.nombre FROM ParteDocumento AS pd WHERE pd.IdDocumento = e.IdDocumento) AS NombreActor
FROM Documentos AS e
INNER JOIN CtRamo AS r ON ( r.IdRamo = e.IdRamoDocumento )
INNER JOIN CtEstado AS edo ON ( edo.CveEstado = e.CveEstado )
INNER JOIN CTDISJUD AS d ON (d.STCT_NUM = e.CveDistrito)
INNER JOIN CTJUZGAD AS j ON (j.CTJU_MUNIC = e.CveDistrito AND j.CTJU_JUZGA = e.CveJuzgado)
LEFT JOIN CtMedioPresentacion AS m ON ( m.IdMedioPresentacion = e.IdMedioPresentacion )
WHERE e.IdTipoDocumento =1 AND e.EsRecibido =1
This is my query. I did the same query in SQL Server and it works!
I am not 100% sure, but i think you can not use table from from clause in a subselect inside of select. But why not simply join the table instead of subselect:
SELECT e.IdDocumento, e.CveDistrito, d.STCT_NOM, e.CveJuzgado, j.CTJU_DESCR, e.NumDocumento, e.IdRamoDocumento, r.Descripcion....., pd.nombreNombreActor
FROM Documentos AS e
INNER JOIN CtRamo AS r ON ( r.IdRamo = e.IdRamoDocumento )
INNER JOIN CtEstado AS edo ON ( edo.CveEstado = e.CveEstado )
INNER JOIN CTDISJUD AS d ON (d.STCT_NUM = e.CveDistrito)
INNER JOIN CTJUZGAD AS j ON (j.CTJU_MUNIC = e.CveDistrito AND j.CTJU_JUZGA = e.CveJuzgado)
LEFT JOIN CtMedioPresentacion AS m ON ( m.IdMedioPresentacion = e.IdMedioPresentacion )
LEFT JOIN ParteDocumento as pd on pd.IdDocumento = e.IdDocumento
WHERE e.IdTipoDocumento =1 AND e.EsRecibido =1

Inner SELECT can't use `u.id` which is in outer SELECT

I have the following MySQL query:
SELECT
COUNT(b.`id`) AS todayOverdue,
DATE_FORMAT(t.`created_time`, "%Y%m%d") AS days
FROM
`Bill` b
LEFT JOIN `Order` o ON b.`order_id` = o.`id`
LEFT JOIN `Trade` t ON o.`trade_id` = t.`id`
LEFT JOIN `User` u ON b.`user_id` = u.`id`
WHERE
b. `deadline` <= "' . $todayTime . '"
AND b. `deadline` >= "' . $todayDate . '"
AND b.`is_paid` = 0
AND (
SELECT
COUNT(b2.`id`)
FROM
`Bill` b2
WHERE
b2.`deadline` <= "' . $todayTime . '"
AND b2.`user_id` = u.`id`
AND b2.`is_paid` = 0
OR (
b2.`deadline` <= b2.`paid_time`
AND b2.`is_paid` = 1
)
) < 2
GROUP BY
days
Why can't the inner SELECT use u.id which is in outer SELECT?
The inner select is completely independent of the outer select. The u table is being joined in the outer select in ways that are unknown to the inner select.
When you have
AND b2.`user_id` = u.`id`
Which row in u is being compared to which row in b2? The server has no way of knowing, so you need to define a table u2 and join it in the inner select.

Query return null in JPA/Hibernate but not in mysql

I'm executing a query but it return null but when i try in sql line cmd it return result.
here is my entity :
#Entity
#Table(name = "appel_offre", catalog = "ao")
public class AppelOffre implements java.io.Serializable {
private Integer idAppelOffre;
...
private Admin userValidation;
private Admin userSaisie;
private Admin userControle;
....
public AppelOffre(Integer idAppelOffre,Admin userSaisie,Admin userControle,Admin userValidation) {
System.out.println("users"); // <-- code not executed
this.idAppelOffre = idAppelOffre;
this.userSaisie = userSaisie;
this.userControle = userControle;
this.userValidation = userValidation;
}
my query is :
#Query(" select new AppelOffre( ao.idAppelOffre , ao.userSaisie , ao.userControle , ao.userValidation ) from AppelOffre ao "
AppelOffre FindAOwithUsers(#Param("idao") Integer idao);
the query generated is :
select appeloffre0_.ID_APPEL_OFFRE as col_0_0_, appeloffre0_.USER_SAISIE as col_1_0_, appeloffre0_.USER_CONTROLE as col_2_0_, appeloffre0_.USER_VALIDATION as col_3_0_
from ao.appel_offre appeloffre0_
inner join ao.admin admin1_ on appeloffre0_.USER_SAISIE=admin1_.ID
inner join ao.admin admin2_ on appeloffre0_.USER_CONTROLE=admin2_.ID
inner join ao.admin admin3_ on appeloffre0_.USER_VALIDATION=admin3_.ID
where appeloffre0_.ID_APPEL_OFFRE=?
I know that the problem is with the inner join they must be left join because in my database just USER_SAISIE which is not null.
i try it with left join like that :
#Query(" select new AppelOffre( ao.idAppelOffre , ao.userSaisie , ao.userControle , ao.userValidation ) from AppelOffre ao "
+ " left join ao.userSaisie "
+ " left join ao.userControle "
+ " left join ao.userValidation "
+ " where ao.idAppelOffre = :idao ")
AppelOffre FindAOwithUsers(#Param("idao") Integer idao);
but it generated double in query :
Hibernate: select appeloffre0_.ID_APPEL_OFFRE as col_0_0_, appeloffre0_.USER_SAISIE as col_1_0_, appeloffre0_.USER_CONTROLE as col_2_0_, appeloffre0_.USER_VALIDATION as col_3_0_
from ao.appel_offre appeloffre0_
left outer join ao.admin admin1_ on appeloffre0_.USER_SAISIE=admin1_.ID
left outer join ao.admin admin2_ on appeloffre0_.USER_CONTROLE=admin2_.ID
left outer join ao.admin admin3_ on appeloffre0_.USER_VALIDATION=admin3_.ID
inner join ao.admin admin4_ on appeloffre0_.USER_SAISIE=admin4_.ID
inner join ao.admin admin5_ on appeloffre0_.USER_CONTROLE=admin5_.ID
inner join ao.admin admin6_ on appeloffre0_.USER_VALIDATION=admin6_.ID
where appeloffre0_.ID_APPEL_OFFRE=?
And also the System.out.println("users"); in my constructor didn't display.
why this didn't work and how can I solve this problem
The constructor isn't called because the query didn't return any results. And it didn't return any results because of inner join used, you're right about that. To make it work use left join, like this
#Query(" select new AppelOffre(ao.idAppelOffre, us, uc, uv) from AppelOffre ao left join ao.userSaisie us left join ao.userControle uc left join ao.userValidation uv "

Limits a left join?

Hi I have a query that pulls the results from a search but I want the left joined results to be limited to 1
Here is the left join:
LEFT JOIN #__ezrealty_siteplan AS sp ON sp.listing_id = a.id "
What I have tried
LEFT JOIN (SELECT * FROM jos_ezrealty LEFT JOIN jos_ezrealty_siteplan AS sp ON (sp.listing_id =jos_ezrealty.id ) LIMIT 1) AS sp ON (sp.listing_id=jos_ezrealty.id)
The entire query:
$query="SELECT a.*, cc.name AS category, ee.ezcity AS proploc, dd.name AS statename, bb.name AS countryname,
u.logo_image AS logo_image, u.mid AS mid, u.dealer_name AS dealer_name, u.dealer_company AS dealer_company,
u.dealer_phone AS dealer_phone, u.dealer_mobile AS dealer_mobile, u.published AS dealerpublished, sp.tenant AS tenant, sp.spacenum AS spacenum, sp.sf AS sf, sp.image AS tenantimage,
u.dealer_type AS dealer_type FROM #__ezrealty as a"
. "\n LEFT JOIN #__ezrealty_catg AS cc ON cc.id = a.cid"
. "\n LEFT JOIN #__ezrealty_locality AS ee ON ee.id = a.locid"
. "\n LEFT JOIN #__ezrealty_state AS dd ON dd.id = a.stid"
. "\n LEFT JOIN #__ezrealty_country AS bb ON bb.id = a.cnid"
. "\n LEFT JOIN #__ezrealty_profile AS u ON u.mid = a.owner"
. "\n LEFT JOIN #__ezrealty_siteplan AS sp ON sp.listing_id = a.id "
. "\n WHERE $extrastring AND a.published = '1' $vacant AND cc.access <= $my->gid $wheres "
. $order.' LIMIT '.$pageNav->limitstart.', '.$pageNav->limit;
In SQL Server, you could use CROSS APPLY. In other DBMS, you can use partitioning (windowing function ROW_NUMBER).
For MySQL, one solution is to use a subquery to get LIMIT 1, then join that to the table, e.g.
select a.col1, a.col2, a.col3, b.col1, b.col2
from
(
select a.col1, a.col2, a.col3, (select b.id as b_id from tbl_b b where b.a_id=a.id limit 1)
from tbl_a a
) a
left join tbl_b b on b.id=a.b_id
I thinks this will give you what you want
SELECT DISTINCT sp.id ,* FROM jos_ezrealty LEFT JOIN jos_ezrealty_siteplan AS sp ON sp.listing_id =jos_ezrealty.id
LEFT JOIN ( SELECT *
FROM #__ezrealty_siteplan
GROUP BY listing_id )
AS sp
ON sp.listing_id = a.id

Mysql query, select 2 databases with 4 tables + nested SELECT?

This is my current query:
$sel = "SELECT
db1t1.userid, db1t1.customer_id, db2t1.customers_id, db2t1.orders_id, db2t2.products_price
FROM
database1.table1 db1t1
LEFT JOIN database2.table1 db2t1 ON
db1t1.customer_id = db2t1.customers_id
LEFT JOIN database2.table2 db2t2 ON
db2t1.orders_id = db2t2.orders_id
WHERE db1t1.userid IN(
SELECT
l.userid, l.username, r.username, r.cus_id
FROM
database1.table3 l
LEFT JOIN database2.table4 r ON
l.username = r.username
WHERE r.cus_id = '1234'
)";
Error message:
Operand should contain 1 column(s)
The error occurred because that you returned a result with multiple columns to an IN clause.
Try this:
SELECT
`db1t1`.`userid`, `db1t1`.`customer_id`, `db2t1`.`customers_id`,
`db2t1`.`orders_id`, `db2t2`.`products_price`
FROM `database1`.`table1` AS `db1t1`
LEFT JOIN `database2`.`table1` AS `db2t1`
USING (`customers_id`)
LEFT JOIN `database2`.`table2` AS `db2t2`
USING (`orders_id`)
WHERE `db1t1`.`userid` IN (
SELECT `l`.`userid`
FROM `database1`.`table3` AS `l`
LEFT JOIN `database2`.`table4` AS `r`
USING (`username`)
WHERE `r`.`cus_id` = 1234
)
What are you trying to achieve ? Maybe we can find a better solution.
Also, I think that you should do an INNER JOIN instead of a LEFT JOIN in the subquery.