I have working query in PostgreSQL:
select s.id, s.seat_number as available_seat, s.row_number as available_row, rm.room_name as screening_room
from seats s
join rooms rm on rm.id=s.room_id
left join (
select r.seat_id from reserved_seats r
join reservations res on res.id=r.reservation_id AND res.screening_id = 3 ) res on res.seat_id=s.id
where res.seat_id is null AND s.room_id=3
ORDER BY s.id;
But I make mistakes translating it into the JPA query language.
Can I use nested SELECTs in JPQL?
The answer is to use native query:
#Query(value =
"SELECT s.id seatId, s.seat_number availableSeat, " +
"s.row_number availableRow, rm.name screeningRoom \n" +
"FROM seats s\n" +
"JOIN rooms rm on rm.id=s.room_id\n" +
" LEFT JOIN (\n" +
" SELECT r.seat_id FROM reserved_seats r\n" +
" JOIN reservations res ON res.id=r.reservation_id " +
" AND res.screening_id = :screeningId) res ON res.seat_id=s.id\n" +
"WHERE res.seat_id IS NULL AND s.room_id=:roomId AND s.row_number=:rowNumber\n" +
"ORDER BY s.id;", nativeQuery = true)
The answer is to use native query:
#Query(value =
"SELECT s.id seatId, s.seat_number availableSeat, " +
"s.row_number availableRow, rm.name screeningRoom \n" +
"FROM seats s\n" +
"JOIN rooms rm on rm.id=s.room_id\n" +
" LEFT JOIN (\n" +
" SELECT r.seat_id FROM reserved_seats r\n" +
" JOIN reservations res ON res.id=r.reservation_id " +
" AND res.screening_id = :screeningId) res ON res.seat_id=s.id\n" +
"WHERE res.seat_id IS NULL AND s.room_id=:roomId AND s.row_number=:rowNumber\n" +
"ORDER BY s.id;", nativeQuery = true)
Related
I'm using JpaRepository and I'm creating a #Query in my repository:
this is my query:
#Query( "SELECT SUM(p.prima) as prima, p.producto as producto, p.tipoProducto as tipoProducto, p.compania as compania, p.cliente as cliente, p.vendedor as vendedor " +
"FROM Poliza p " +
"JOIN Producto pr ON p.producto=pr " +
"JOIN TipoProducto tp ON p.tipoProducto=tp " +
"JOIN Compania c ON p.compania=c " +
"JOIN Cliente cl ON p.cliente=cl " +
"LEFT JOIN Vendedor v ON p.vendedor=v " +
"WHERE p.comienzo >=?1 " +
"AND p.comienzo <= ?2 " +
"GROUP BY p.producto")
and I realize that I only get the rows where "Vendedor" is present.
I used the spring.jpa.show-sql=true property to check what was going on and I realize that the query is creating an inner join for each property in the SELECT STATEMENT
inner join producto producto1_ on (poliza0_.producto=producto1_.id)
inner join tipo_producto tipoproduc2_ on (poliza0_.tipo_producto=tipoproduc2_.id)
inner join compania compania3_ on (poliza0_.compania=compania3_.id)
inner join cliente cliente4_ on (poliza0_.cliente=cliente4_.id)
inner join vendedor vendedor5_ on (poliza0_.vendedor=vendedor5_.id)
join producto producto6_ on poliza0_.producto=producto6_.id
join tipo_producto tipoproduc7_ on poliza0_.tipo_producto=tipoproduc7_.id
join compania compania8_ on poliza0_.compania=compania8_.id
join cliente cliente9_ on poliza0_.cliente=cliente9_.id
left join vendedor vendedor10_ on poliza0_.vendedor=vendedor10_.id
As you can see in the first part I have an inner join from Vendedor which makes the query wrong.
How should I create my query to get the expected result?
if understand clearly
#Query( "SELECT SUM(p.prima) as prima, p.producto as producto, p.tipoProducto as tipoProducto, p.compania as compania, p.cliente as cliente, p.vendedor as vendedor " +
"FROM Poliza p " +
"JOIN Producto pr ON p.producto=pr " +
"JOIN TipoProducto tp ON p.tipoProducto=tp " +
"JOIN Compania c ON p.compania=c " +
"JOIN Cliente cl ON p.cliente=cl " +
"LEFT JOIN Vendedor v ON p.vendedor=v " +
"WHERE p.comienzo >=?1 " +
"AND p.comienzo <= ?2 " +
"GROUP BY p.producto")
i think you can using v instead p.vendedor as vendedor in select field.
If I read correctly, you are defining your own query. So, you can edit the JOIN in your query and write LEFT JOIN instead.
Am I right on your intentions?
I need to use window functions within a Spring Data Repository, is
this possible?
I am now using java spring maven and I have no knowledge about the entity table partition in JPA.
My SQL Query
select
b.q_stop_id as q_stop_id,
b.q_work_day as q_work_day,
b.q_work_end as q_work_end,
b.q_mc_num as q_mc_num,
b.q_mc_name as q_mc_name,
b.Hnbn as q_hnbn,
b.q_koku as q_koku,
b.q_stop_st_time as q_stop_st_time,
b.q_stop_en_time as q_stop_en_time,
b.q_stop_time_s as q_stop_time_s,
b.q_stop_maj_code as q_stop_maj_code,
b.q_stop_major as q_stop_major,
b.q_stop_num as q_stop_num,
b.q_stop_minor as q_stop_minor,
b.q_pause_flag as q_pause_flag
from
(
select ROW_NUMBER() OVER (PARTITION BY a.rnk
ORDER BY a.q_stop_st_time,a.q_stop_en_time) AS RowNo,COUNT(*) OVER () as cnt,*
from (
select DENSE_RANK() OVER(PARTITION BY proL.q_set_hnbn ORDER BY stL.q_stop_st_time,stL.q_stop_en_time DESC) as rnk,case when proL.q_set_hnbn is not null and proL.q_set_hnbn !='' then proL.q_set_hnbn else proL.q_hnbn end as Hnbn ,proL.q_set_hnbn as setHnbn, stL.q_stop_id as q_stop_id,wk.q_work_day as q_work_day,wk.q_work_end as q_work_end,mc.q_mc_num as q_mc_num,mc.q_mc_name as q_mc_name,proL.q_hnbn as q_hnbn,proL.q_koku as q_koku,stL.q_stop_st_time as q_stop_st_time,stL.q_stop_en_time as q_stop_en_time,stL.q_stop_time_s as q_stop_time_s,mst.q_stop_maj_code as q_stop_maj_code,mst.q_stop_major as q_stop_major,mst.q_stop_num as q_stop_num,mst.q_stop_minor as q_stop_minor,
mst.q_pause_flag as q_pause_flag
from T_STOP_LOG stL inner join M_stop_item mst on stL.q_stop_num=mst.q_stop_num
inner join T_work_log wk on stL.q_work_id=wk.q_work_id
inner join T_prod_log proL on wk.q_work_id =proL.q_work_id
inner join M_mc mc on wk.q_mc_num=mc.q_mc_num
left join T_malfunction_repair_log r on r.q_stop_id=stL.q_stop_id
where wk.q_work_day >='2021-04-19 00:00:00.000' and
wk.q_work_end<='2021-04-20 23:59:59.000' and mc.q_mc_num='1200' )a
)b where b.RowNo=1 or b.RowNo=2
> I found the solution by using JPA nativeQuery = true
#Query(value = "select " + "b.q_stop_id as q_stop_id," + "b.q_work_day as q_work_day,"
+ "b.q_work_end as q_work_end," + "b.q_mc_num as q_mc_num," + "b.q_mc_name as q_mc_name,"
+ "b.Hnbn as q_hnbn," + "b.q_koku as q_koku," + "b.q_stop_st_time as q_stop_st_time,"
+ "b.q_stop_en_time as q_stop_en_time," + "b.q_stop_time_s as q_stop_time_s,"
+ "b.q_stop_maj_code as q_stop_maj_code," + "b.q_stop_major as q_stop_major,"
+ "b.q_stop_num as q_stop_num," + "b.q_stop_minor as q_stop_minor," + "b.q_pause_flag as q_pause_flag "
+ "from" + "(" + "select ROW_NUMBER() OVER (PARTITION BY a.rnk "
+ "ORDER BY a.q_stop_st_time,a.q_stop_en_time) AS RowNo,COUNT(*) OVER () as cnt,* "
+ "from (select DENSE_RANK() OVER(PARTITION BY proL.q_set_hnbn ORDER BY stL.q_stop_st_time,stL.q_stop_en_time DESC) as rnk,case when proL.q_set_hnbn is not null and proL.q_set_hnbn !='' then proL.q_set_hnbn else proL.q_hnbn end as Hnbn ,proL.q_set_hnbn as setHnbn,stL.q_stop_id as q_stop_id,wk.q_work_day as q_work_day,wk.q_work_end as q_work_end,mc.q_mc_num as q_mc_num,mc.q_mc_name as q_mc_name,proL.q_hnbn as q_hnbn,proL.q_koku as q_koku,stL.q_stop_st_time as q_stop_st_time,stL.q_stop_en_time as q_stop_en_time,stL.q_stop_time_s as q_stop_time_s,mst.q_stop_maj_code as q_stop_maj_code,mst.q_stop_major as q_stop_major,mst.q_stop_num as q_stop_num,mst.q_stop_minor as q_stop_minor,"
+ "mst.q_pause_flag as q_pause_flag "
+ "from T_STOP_LOG stL inner join M_stop_item mst on stL.q_stop_num=mst.q_stop_num "
+ "inner join T_work_log wk on stL.q_work_id=wk.q_work_id "
+ "inner join T_prod_log proL on wk.q_work_id =proL.q_work_id "
+ "inner join M_mc mc on wk.q_mc_num=mc.q_mc_num "
+ "left join T_malfunction_repair_log r on r.q_stop_id=stL.q_stop_id "
+ "where wk.q_work_day >=:workDay and wk.q_work_end<=:workEnd and mc.q_mc_num=:kiban)a "
+ ")b where b.RowNo=1 or b.RowNo=2", nativeQuery = true)
I have a SQL query for get two table of SELECT.
I want to get two table as entity in result.
these tables are some column's name is equal(id,version).
I have following code :
String sql = "select sepTemp.*,pspTerm.* " +
"from SEPTRANSACTIONTEMP sepTemp " +
"LEFT JOIN PSP_Terminal pspTerm ON (pspTerm.idInPSP=sepTemp.termid AND pspTerm.pspID=:pspID) " +
"where NOT EXISTS " +
"(select * from PSPTRANSACTION pspTrans where pspTrans.PSPID=:pspID AND pspTrans.termNo=sepTemp.rrn) ";
List<Object[]> sepTransactionTemps = em.createNativeQuery(sql)
.setParameter("pspID", PSPTypes.SEP.getType())
.getResultList();
sepTransactionTemps.forEach(row -> {
SEPTransactionTemp sepTransactionTemp = ((SEPTransactionTemp) row[0]);
PSPTerminal sepTransactionTemp = ((PSPTerminal) row[1]);
...
but throw exception following :
org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException: Encountered a duplicated sql alias [ID] during auto-discovery of a native-sql query
column id exists in your tables (SEPTRANSACTIONTEMP, LEFT JOIN PSP_Terminal)
create an alias for id column in your select query
String sql = "select " +
"sepTemp.id as sepTemp_id, " +
"sepTemp.version as sepTemp_version, " +
"pspTerm.id as pspTerm_id, " +
"pspTerm.version as pspTerm_version " // try here add all your column names
+ " from SEPTRANSACTIONTEMP sepTemp LEFT JOIN PSP_Terminal pspTerm "
+ "ON (pspTerm.idInPSP=sepTemp.termid AND pspTerm.pspID=:pspID) " + "where NOT EXISTS "
+ "(select * from PSPTRANSACTION pspTrans where pspTrans.PSPID=:pspID AND pspTrans.termNo=sepTemp.rrn) ";
List<Object[]> sepTransactionTemps = em.createNativeQuery(sql).setParameter("pspID", PSPTypes.SEP.getType())
.getResultList();
I have this Query in my JPA repository - and it works EXCEPT the " order by " part. Am i doing this wrong ? is it different in hql ?
#Query(value = "select wm.WagerIdentification, wm.BoardNumber, wm.MarkSequenceNumber, wm.MarkNumber," +
" pt.CouponTypeIdentification, pt.WagerBoardQuickPickMarksBoard " +
"from WagerBoard wb " +
"inner join wb.listOfWagerMarks wm " +
"inner join wb.poolgameTransaction pt " +
"where wb.WagerIdentification = wm.WagerIdentification and wb.BoardNumber = wm.BoardNumber and wb.GameIdentification = wm.GameIdentification and wm.meta_IsCurrent = 1 " +
"and wb.TransactionIdentification = pt.TransactionIdentification and pt.meta_IsCurrent = 1 " +
"and wb.meta_IsCurrent = 1 order by wm.WagerIdentification asc, wm.BoardNumber asc, wm.MarkNumber asc")
Instead of ordering result within the #Query, you can add a method parameter of type Sort, like in Spring Data JPA reference
Error:
org.hibernate.hql.ast.QuerySyntaxError: unexpected token
org.hibernate.hql.ast.QuerySyntaxError: unexpected token: ON near line
1, column 148 [SELECT op.username, op.email, orders.p_id, orders.o_id,
product.listed_price FROM com.model.Orders orders INNER JOIN
orders.OrderProcessing as op ON op.u_id = orders.u_id INNER JOIN
orders.Product as product ON product.p_id = orders.p_id WHERE
product.p_id = '208' ORDER BY op.username]
productList =
(List<Object[]>) session.createQuery("SELECT op.username, op.email, orders.p_id, orders.o_id, product.listed_price " +
"FROM Orders orders " +
"INNER JOIN orders.OrderProcessing as op " +
"ON op.u_id = orders.u_id " +
"INNER JOIN orders.Product as product " +
"ON product.p_id = orders.p_id " +
"WHERE product.p_id = '"+p_id +"' " +
"ORDER BY op.username").list();
Join restrictions are supported by Hibernate but the syntax is not the same than SQL. You have to replace the ON keyword by WITH in Hibernate !
productList = (List<Object[]>) session.createQuery("SELECT op.username, op.email, orders.p_id, orders.o_id, product.listed_price " + "FROM Orders orders " +"INNER JOIN orders.OrderProcessing as op " + "ON op.u_id = orders.u_id"+ "INNER JOIN orders.Product as product " + "ON product.p_id = orders.p_id "+ "WHERE product.p_id = '"+p_id +"'" "ORDER BY op.username").list();
You have to check the Orders table. orders.orderProcessing is not a table its a column from orders table.
Chetter Hummin is right, "on" isn't supported in HQL.
See this: http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html