how can join two query in PostgreSQL - sql

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

Related

Using sub-select in FROM clause inside JPA #NamedQuery

In my app I need to use #NamedQuery to find the type of the most frequent operation assigned to specific account
#Entity
#Table(name="\"ACCOUNTOPERATION\"")
#NamedQuery(name="AccountOperation.findTypeOfMostFrequentOperation", query="" +
"SELECT ao.type from AccountOperation ao WHERE ao.account.id = ?1 " +
"GROUP BY ao.type HAVING COUNT(ao) = (" +
"SELECT MAX(typeCountQuery.typeCount) " +
"FROM (" +
"SELECT COUNT(aop) as typeCount " +
"FROM AccountOperation aop WHERE aop.account.id = ?1 GROUP BY aop.type" +
") as typeCountQuery" +
")"
)
public class AccountOperation {
#ManyToOne
private Account account;
private BigDecimal amount;
private OperationType type;
...
Right after FROM clause at '(' character, which begins typeCountQuery's body I'm getting
')', ',', GROUP, HAVING, IN, WHERE or identifier expected, got '('
I've read that JPA does not support sub-selects in the FROM clause, so is there any way to rewrite SQL code to still use it in #NamedQuery?
I'm using IntelliJ IDE with H2 DB and with eclipselink and javax.persistence in dependencies.
Link to source
In JPQL, you cannot use subqueries. To resolve this issue, you need to use some keywords like ALL, ANY, which work similiar.
So in your situation it could be:
#NamedQuery(name="AccountOperation.findTypeOfMostFrequentOperation", query="" +
"SELECT ao.type from AccountOperation ao WHERE ao.account.id = ?1 " +
"GROUP BY ao.type HAVING COUNT(ao) >= ALL (" +
"SELECT COUNT(aop) as typeCount " +
"FROM AccountOperation aop WHERE aop.account.id = ?1 GROUP BY aop.type)"
The type with a highest count returns the following query
select type
from AccountOperation
where id = ?
group by type
order by count(*) desc
fetch first 1 ROWS only
You should be anyway avare of the existence of ties, i.e. more types with the identical maximal count and should make some thought how to handle them.
I.e. in Oracle you may say fetch first 1 ROWS WITH TIES to get all the types with tha maximal count.

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 :)

How to transform SQL query into JPQL query?

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).

Order of JSON returned by ORMLite?

I'm new to web services and trying to query some tables using ORMLite, it doesn't support join statements so I'm using a raw query. I was wondering if there is a way to specify how the JSON is returned. What I have right now is:
Dao<CodesModel,String> CodesDao = DaoManager.createDao(connectionSource, CodesModel.class);
GenericRawResults<String[]> rawResults =
CodesDao.queryRaw(
"select r.CodeA, s.SubCodeA, r.CodeB, s.SubCodeB " +
"from CodesTable r JOIN SubCodesTable s ON s.CodeA = r.CodeA " +
"where SubCodeB = '" + b_sub + "' AND r.CodeB = '" + b_code + "'");
And the results are returned as a String[] and always seem to be in the order of
[CodeA, SubCodeA, CodeB, SubCodeB]
but I have only tested this locally and can't find in the documentation what determines the order for variables in the array that is returned.
The results are ordered that way because that is the order in which you specified them in the select statement. If you want the results ordered in a different way, reorder them in your query.
If anyone is looking for a way to know column names when using "select *" you can also use "getColumnNames()" on the rawResults object and they will always be in the order that the results are. Examples
//The result is returned as a GenericRawResults object
List<String[]> results = rawResults.getResults();
String[] columns = rawResults.getColumnNames();
JSONObject obj = new JSONObject();
if(results.size()>0)
{
obj.put(columns[0], results.get(0)[0]);
obj.put(columns[1], results.get(0)[1]);
obj.put(columns[2], results.get(0)[2]);
obj.put(columns[3], results.get(0)[3]);
}

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.