How to transform SQL query into JPQL query? - sql

I'm looking for how to transform the following query (SQL) into query JPQL;
SELECT * FROM equipements eq
LEFT JOIN check_lists checks
ON eq.id_equipements = checks.equipements_id
LEFT JOIN responses_check_lists resp
ON checks.id_check_lists = resp.check_lists_id
AND resp.missions_id = 15
AND eq.id_equipements = 1
ORDER BY checks.id_check_lists
I followed the documents on the internet but I do not get the correct transformation of my query in JPQL.
I know that the attributes of the query will be replaced by the attributes of the class.
I posted here to help me in transforming the SQL query.
Edit1:
#Query(
"SELECT r, checks, eq"
+ " FROM Equipements eq"
+ " LEFT JOIN CheckLists checks "
+ " ON eq.idEquipements = checks.equipements.idEquipements"
+ " LEFT JOIN ResponsesCheckLists r"
+ " ON checks.idCheckLists = r.CheckLts.idCheckLists"
+ " AND r.Respmission.idMission= :idmiss "
+ " AND eq.idEquipements= :idEqp"
+ " ORDER BY checks.idCheckLists ASC"
)
Error of Edit1:
Caused by: java.lang.IllegalStateException: No data type for node:
org.hibernate.hql.internal.ast.tree.IdentNode +-[IDENT] IdentNode:
'r' {originalText=r}
org.hibernate.hql.internal.ast.InvalidPathException: Invalid path:
'checks.idCheckLists'
Thank you in advance,

Analysing your SQL and without see the entities, your JPQL can be something like this:
SELECT eq FROM Equipements eq
LEFT JOIN eq.checks check
LEFT JOIN check.responses resp
LEFT JOIN resp.missions mission WITH mission.id = :idmiss
WHERE eq.id = :idEqp
ORDER BY check.id
But, to be something like this, you need to adjust the mapping of your entities (entity name, column names, etc).

Related

how can join two query in PostgreSQL

I want to join two querys into one query.
What retrieved in the first query is a tables with column of resourceindex that sorts ascending:
String loadRates = "SELECT * FROM ratings WHERE userindex="
+ uindex
+ " ORDER BY rank DESC";
And in the second query, what should retrieved is rows of resourceindexes:
String loadResources = "SELECT * FROM resourceinfo WHERE resourceindex = "
+ rs.getInt("resourceindex");
How can I combine these into a single query?
Do not use old style join but use the keyword join.
Never ever write an SQL string like that with concatenation of parameters but use parameters instead.
"SELECT * FROM public.resourceinfo"
+ " inner join public.ratings ON ratings.resourceindex = resourceinfo.index"
+ " WHERE ratings.userindex = $1" +
+ " ORDER BY ratings.rank DESC;";
How you would apply the parameters depend on the language you are using which you didn't tag.
EDIT: If you meant it would also filtered by a resourceindex parameter then add it too as:
AND resourceinfo.index = $2

Unknow column in ON clause

I have the following query:
select p.idPerson from person p "
+ " join dog g on g.idDog = p.idDog, "
+ " tree t "
+ " join parents p1 on p1.idParents = t.idParents "
+ " join parents p2 on p2.idParents = p.idParents "
I've changed parameters, i know these query doesn't make sense, i'ts just to show you the structure, so my error is:
Unknown column 'p.idParents' in 'on clause'
This does even less sense, i think the error is on the "tree t", the only one which is not join, but i don't know how to solve it becuase it hasn't got any relation with the other tables to do a join.
Thanks!

ConcatRelated() - query or tables

I have similar issue to this question Combine values from related rows into a single concatenated string value.
I've got two queries:
This is what it looks like now without ConcatRelated():
I need to get return:
I tried to use this SQL:
SELECT DISTINCT
Q_Fakt1.FakturaID,
Q_Fakt1.DatumVystavenia,
Q_Fakt1.DatumSplatnosti,
Q_Fakt2.Pismeno,
ConcatRelated(
"pismeno",
"Q_Fakt2",
"FakturaID = '" & [Q_Fakt1]![FakturaID] & "'"
) AS Letters
FROM Q_Fakt1 INNER JOIN Q_Fakt2 ON Q_Fakt1.FakturaID = Q_Fakt2.FakturaID;
Result is 7× popup:
ConcatRelated() Error3464: Data type mismatch in criteria expression.
I did the same with Tables but I have little bit more complicated Relations so...
https://i.stack.imgur.com/TM7Cu.png
SQL:
SELECT DISTINCT
Faktury.FakturaID,
Kategorie.Oznacenie,
Faktury.DatumVystavenia,
FakturujemVam.FakturujemVamID,
FakturyDetaily.FakturujemVam,
[DatumVystavenia]+[splatnostFaktury] AS DatumSplatnosti,
ConcatRelated("Oznacenie","kategorie","FakturaID = '" & [FakturaID] & "'") AS Letters
FROM Kategorie INNER JOIN (Faktury INNER JOIN (FakturujemVam INNER JOIN FakturyDetaily ON FakturujemVam.FakturujemVamID = FakturyDetaily.FakturujemVam) ON Faktury.FakturaID = FakturyDetaily.Faktura) ON Kategorie.KategoriaID = FakturujemVam.Kategoria;
Result is 6× popup:
ConcatRelated() Error3061: Too Few parameters. Excepted 1.
Where did I go wrong? Thank you for Help
That's because you're using string delimiters when you're not using a string.
Remove those delimiters, and it will work fine:
ConcatRelated("Oznacenie","kategorie","FakturaID = " & [FakturaID] ) AS Letters
SOLVED:
STEP 1
Create Query to merge more tables in one
Datasheet View
Design View
STEP 2
Create another Query & Use ConcatRelated()
Design View
SQL:
SELECT
Q_Part_Bill_Num2.NumBill,
Q_Part_Bill_Num2.C_Mark,
ConcatRelated(
"C_Mark",
"Q_Part_Bill_Num2",
"Q_Part_Bill_Num2!NumBill = " & [Q_Part_Bill_Num2]![NumBill]
) AS PartBillNum2
FROM Q_Part_Bill_Num1 INNER JOIN Q_Part_Bill_Num2 ON Q_Part_Bill_Num1.NumBill = Q_Part_Bill_Num2.NumBill;
STEP 3 - Optional
Edit MODULE to delete / change separator ", "
STEP 4
Create One Last Query to Concatenate everything together.
Design View
SQL:
SELECT DISTINCT
Q_Part_Bill_Num1.PartBillNum1,
Q_Part_Bill_Num3.PartBillNum2,
[PartBillNum1] & [PartBillNum2] AS [Full]
FROM
(T_Bills INNER JOIN Q_Part_Bill_Num1 ON T_Bills.Bills_ID = Q_Part_Bill_Num1.Bills_ID)
INNER JOIN (Q_Part_Bill_Num2 INNER JOIN Q_Part_Bill_Num3
ON (Q_Part_Bill_Num2.NumBill = Q_Part_Bill_Num3.NumBill)
AND (Q_Part_Bill_Num2.C_Mark = Q_Part_Bill_Num3.C_Mark))
ON Q_Part_Bill_Num1.NumBill = Q_Part_Bill_Num2.NumBill;
Use DISTINCT to avoid duplicates.
I Hope this will help someone.
Thank you all, for your time :)

ebean query with subquery

I'm trying to do using EBean the equivalent of
select * from myTable1 where id not in (select id2 from myTable2) ;
I have no reference of table1 Object in table2 Object and the same the other way around.
Does anyone knows how to that using EBean ?
For the moment all I have is :
List<MyTable1> myResult = MyTable1.find.where().eq("id","1" ).findList();
Thanks.
C.C.
Apparently it has been possible to do this since 2009 using the example given in this bug report:
http://www.avaje.org/bugdetail-92.html
The example:
Query<Product> subQuery =
Ebean.createQuery(Product.class)
.select("sku")
.where().idEq(4).query();
List<MinCustomer> list = Ebean.find(MinCustomer.class)
.where().in("name", subQuery)
.findList();
However:
I am unable to make it work because the SQL generated is invalid. Seemingly due to a string replacement happening behind the scene in Ebean where (for me at least) the table name in the subquery is lost.
I expect it has to do with my main query includes a reference to the table from which my subquery "is selecting".
Turning the valid SQL from the example:
select c.id, c.name, c.notes
from o_customer c
where (c.name) in (select p.sku from o_product p where p.id = ? )
... into this invalid SQL in my case:
select t0.id as c0, ... t0.location_id as c8
from myRecordClass t0
where (t0.location_id) in (
select t0.id
from t0.location_id t0 # should be: from location t0
where t0.customer_id = ?
) and t0.creation > ?
order by t0.creation desc
The workaround:
Use the RawSql approach like in https://stackoverflow.com/a/27431625/190599 - example here:
String sql = "select b.id, b.location_id ... " +
"from myRecordClass b " +
"where location_id in (" +
"select id " +
"from location " +
"where customer_id = " + user.getCustomer().getId() +
") " +
"order by creation desc limit 10";
RawSql rawSql = RawSqlBuilder
.parse(sql)
.columnMapping("b.id", "id")
.columnMapping("b.location_id", "location.id")
....
.create();
Query<MyRecordClass> query = Ebean.find(MyRecordClass.class);
query.setRawSql(rawSql);
final List<MyRecordClass> list = query.findList();
I hardly believe that RawSql is fastest way to achieve this kind of query, it allows you to return list of mapped objects.
It's also possible to use SqlQuery (described in Reference guide (PDF)) to fetch a list of SqlRows - so you can find required data without any mapping at all.

How to combine asterix syntax with table abbreviations

Is it possible to combine * syntax with table abbreviations?
I want to do something like:
"SELECT subfunds.* FROM subfunds S" +
" INNER JOIN funds F ON S.id_fund = F.id" +
" WHERE F.fund_short IN('" + stSQLFundList + "')"
The above code gets a syntax error
"invalid reference to FROM-clause entry for table "subfunds".
I already found that if I do
"SELECT * FROM subfunds S" +
" INNER JOIN funds F ON S.id_fund = F.id" +
" WHERE F.fund_short IN('" + stSQLFundList + "')"
then I get all fields from both tables rather than from the subfunds table only.
So how do I get all fields from the first table (and none of the other tables' fields) in my answer set while also being able to use the single-letter table abbreviations?
Change your code to this and you will get all fields from subfunds.
"SELECT S.* FROM subfunds S" +
" INNER JOIN funds F ON S.id_fund = F.id" +
" WHERE F.fund_short IN('" + stSQLFundList + "')"
If you are using an alias, then you want to reference that table by it's alias.