I have to write a single select query to fetch all details from seven tables. Earlier I had separate queries but now I am working on optimizing the queries.
The following is my table structure :
Main Table (SN, model , regId) -- 1 row
Table1(col1,col2....SN) - SN is forienKey -- 1 row
Table2(col1,col2,....SN) - SN is forienKey -- 1 row
Table3(col1,col2,.....regId) - regId is forienKey -- 1 row
Table4(col1,col2,.....regId) - regId is forienKey - 2 rows
Table5(col1,col2,.....regId) - regId is forienKey - 2 rows
Table6(col1,col2,.....regId) - regId is forienKey - 1 row
There is a one to many mapping between the main table and table 4 and table 5.
I have tried using inner join to fetch the rows but I am getting duplicate values. Below is the query that I have written. Is there anything I am missing?
select * from MainTable
inner join Table1 on MainTable.SN = Table1.SN
inner join Table2 on MainTable.SN = Table2.SN
inner join Table3 on MainTable.regId = TABLE3.regId
inner join TABLE4 on MainTable.regId = Table4.regId
inner join TABLE5 on MainTable.regId = Table5.regId
inner join TABLE6 on MainTable.regId = Table6.regId
try joining tables like below to join all of them together
select * from (select * from MainTable
inner join Table1 on MainTable.SN = Table1.SN
inner join Table2 on Table1.SN = Table2.SN ) tempMain
inner join Table3 on tempMain.regId = TABLE3.regId
inner join TABLE4 on TABLE3.regId = Table4.regId
inner join TABLE5 on Table4.regId = Table5.regId
inner join TABLE6 on Table5.regId = Table6.regId
though from your example i don't know if table2 & table 3 are related. anyways you can try to find similar.
Related
tl;dr I have a long native query in Hibernate, that is split in multiple queries (with table as ...). This Query use inner joins that not work in hibernate (empty result), but work excellent in the SQL Console. Also if I copy/paste the query from the hibernate logs into the console.
with params as (select ca.id as calculation_id, chart_id, range_size, range_size * interval '1' minute as size
from calculation ca
inner join chart c on c.id = ca.chart_id
inner join time_range tr on tr.id = c.time_range_id
where ca.id = :calculationid),
tuple_diff as (select t.calculation_id,
t.id,
t.ohlc_id,
t.time, t.time - lag(t.time, 1) over (order by t.time) as diff
from tuple t inner join params p
on t.calculation_id = p.calculation_id),
ohlc_diff as (select o.chart_id,
o.id,
o.time,
o.time - lag(o.time, 1) over (order by o.time) as diff
from ohlc o inner join params p on o.chart_id = p.chart_id),
tuple_filtered as (select id, ohlc_id, time, diff, p.size, p.range_size
from tuple_diff t
inner join params p on chart_id = p.chart_id
where diff <> p.size),
ohlc_filtered as (select o.chart_id, o.id as ohlc_id, time
from ohlc_diff o
inner join params p on o.chart_id = p.chart_id
where o.diff <> p.size)
select t.time as time, t.range_size as size
from tuple_filtered t
left join ohlc_filtered o on t.time = o.time
where o.ohlc_id is null
order by t.time;
The long version, I have a microservice, generated with jhipster and the project runs productive with PostgreSQL and in development mode with a H2 Database. I have ohlc stockexchange time series and calculate calculations with an other microservice and store the computation in a tuple table. Sometimes I have holes in the timeline and want to recalculate them. I need to get the time difference to the last calculation. This is not an easy SQL Query, because you need to access the previous row like in Excel. I use the lag function to solve this problem. But the lag function is not the reason.
I generate a test project with an integration test to analyze the problem. The Junit Test is de.bitc.se.service.CalculationServiceIT and run with a Postgresql Testcontainer. The test also fill the SQL tables with testdata. I start to split the query in small parts.
with params as (select ca.id as ca_id,
chart_id, range_size,
range_size * interval '1' minute as size
from calculation ca
inner join chart c on c.id = ca.chart_id
inner join time_range tr on tr.id = c.time_range_id
where ca.id = :calculationid)
select ca_id, chart_id, range_size
from params
order by ca_id;
This part works like the console.
with tuple_diff as (select t.calculation_id,
t.id,
t.ohlc_id,
t.time,
t.time - lag(t.time, 1) over (order by t.time) as diff
from tuple t
where calculation_id = :calculationid)
select calculation_id, time
from tuple_diff
order by calculation_id;
The second query too, but when I try to join the query's, I got an empty result:
with params as (select ca.id as ca_id,
chart_id,
range_size, range_size * interval '1' minute as size
from calculation ca
inner join chart c on c.id = ca.chart_id
inner join time_range tr on tr.id = c.time_range_id
where ca.id = :calculationid),
tuple_diff as (select t.calculation_id,
t.id,
t.ohlc_id,
t.time,
t.time - lag(t.time, 1) over (order by t.time) as diff
from tuple t
inner join params p on p.ca_id = t.calculation_id
where calculation_id = ca_id)
select calculation_id
from tuple_diff
order by calculation_id;
When I try to join the param query (one result) with the tuple table I got no result. In the SQL console I got a result of multiple lines. I used the EntityManager to exclude Spring Data code in the splitted queries in the integration test.
I have no idea why I got no result. Is it a bug in Hibernate or a mistake?
I'm having problems with the following query from SQL to Hibernate HQL:
select
(lot of things from table 1)
from
table1
inner join
table2 on table1.investigationEvent = table2.id_investigationEvent
inner join
table3 on table2.eventSection = table3.sectionEventsCod
inner join
table4 on table3.sectionEventsCod = table4.investigationSectionEvent
In HQL I wrote this:
Select blabla
+ "FROM table1 t1 "
+ "INNER JOIN t1.investigationEvent t2 "
+ "INNER JOIN t2.eventSection t3 , "
+ "table4 t4
INNER JOIN t4.investigationSectionEvent t3 "
+ "WHERE iset.typology.idTypology = :idTypology "
+ "WHERE ast.typology.idTypology = :idTypology ";
The problem is that with this syntax i can make joins from:
table 1 - > table 2
table 2 - > table 3
but i can't make the join
table 3 -> table 4
since the table 3 bean doesen't have any attribute to go to table 4 bean. However, is possibile make the contrary:
table 4 - > table 3 (since table 4 contains an attribute table 3 bean)
The problem is: using this syntax i have to call a second FROM (table4, as you can see from my hql query). Can you solve my problem? I have to make the query calling only the first table with FROM then using all JOIN(s).
This is Some Beans:
Table 1 {
...
Table 2 investigationEvent; }
Table 2 {
...
Table 3 eventSection
and then
Table 4{
...
Table3 investigationSectionEvent; }
The problem is that Table 3 doesen't contain Table 4.
While running Hibernate Criteria, HQL query is not created in given order
and shows Exception
ERROR SqlExceptionHelper:131 - Unknown column 'stsup4_.SUPPLIER_ID' in 'on clause'
The Generated HQL is not created in expected order.
When I run the same generated HQL in mysql with some changes, I get output.
Java Code is given Below
Session session = connector.getSession();
Criteria cr = session.createCriteria(ST_PRODUCTMASTER.class, "ST_PRODUCT");
cr.createCriteria("ST_PRODUCT.ST_PRODUCT_MANUFACTURER_PARENT", "STPRODMAN", JoinType.LEFT_OUTER_JOIN, Restrictions.eq("PROD_MAN_STATUS", "ACTIVE"));
cr.createCriteria("STPRODMAN.ST_MANUFACTURER", "STMAN", JoinType.LEFT_OUTER_JOIN);
cr.createCriteria("ST_PRODUCT.ST_PRODUCT_SUPPLIER_PARENT", "STPRODSUP", JoinType.LEFT_OUTER_JOIN, Restrictions.eq("PROD_SUPPLIER_STATUS", "ACTIVE"));
cr.createCriteria("STPRODSUP.ST_SUPPLIER", "STSUP", JoinType.LEFT_OUTER_JOIN);
cr.createCriteria("ST_PRODUCT.ST_PRODUCT_RATES", "ZSTPR", JoinType.LEFT_OUTER_JOIN, Restrictions.eqProperty("ST_SUPPLIER.SUPPLIER_ID", "STSUP.SUPPLIER_ID"));
cr.createCriteria("ST_PRODUCT.ST_MEDICINE_CATEGORY", "MEDI_CAT", JoinType.LEFT_OUTER_JOIN);
cr.createCriteria("ST_PRODUCT.ST_TAX_MASTER", "TAX", JoinType.INNER_JOIN);
cr.createCriteria("ST_PRODUCT.ST_UNIT", "UNIT", JoinType.INNER_JOIN);
cr.add(Restrictions.eq("ST_PRODUCT.PRODUCT_STATUS", "ACTIVE"));
ProjectionList p1 = Projections.projectionList();
p1.add(Projections.property("ST_PRODUCT.PRODUCT_ID"));
p1.add(Projections.property("ST_PRODUCT.PRODUCT_NAME"));
p1.add(Projections.property("UNIT.UNIT_DISPLAY_UNIT"));
p1.add(Projections.property("TAX.TAX_PURCHASE"));
p1.add(Projections.property("ST_PRODUCT.PRODUCT2_DISCOUNT"));
p1.add(Projections.property("ST_PRODUCT.PRODUCT2_DIS_AMOUNT"));
p1.add(Projections.property("ST_MEDICINE_CATEGORY.CAT_CATEGORY_ID"));
p1.add(Projections.property("MEDI_CAT.CAT_SHORT_NAME"));
p1.add(Projections.property("UNIT.UNIT_ID"));
p1.add(Projections.property("TAX.TAX_ID"));
//MANUFACTURER
p1.add(Projections.property("STMAN.MAN_ID"));
p1.add(Projections.property("STPRODMAN.BASE_LEVEL"));
p1.add(Projections.property("STPRODMAN.FREE_QTY"));
//SUPPLIER
p1.add(Projections.property("STSUP.SUPPLIER_ID"));
p1.add(Projections.property("STPRODSUP.BASE_LEVEL"));
p1.add(Projections.property("STPRODSUP.FREE_QTY"));
cr.setProjection(p1);
List l = cr.list();
System.out.println("Size items::" + l.size());
ERROR SqlExceptionHelper:131 - Unknown column 'stsup4_.SUPPLIER_ID' in 'on clause'
This it the SQL generated by Hibernate
select
this_.PRODUCT_ID as y0_,
this_.PRODUCT_NAME as y1_,
unit8_.UNIT_DISPLAY_UNIT as y2_,
tax7_.TAX_PURCHASE as y3_,
this_.PRODUCT2_DISCOUNT as y4_,
this_.PRODUCT2_DIS_AMOUNT as y5_,
this_.CAT_CATEGORY_ID as y6_,
medi_cat6_.CAT_SHORT_NAME as y7_,
unit8_.UNIT_ID as y8_,
tax7_.TAX_ID as y9_,
stman2_.MAN_ID as y10_,
stprodman1_.BASE_LEVEL as y11_,
stprodman1_.FREE_QTY as y12_,
stsup4_.SUPPLIER_ID as y13_,
stprodsup3_.BASE_LEVEL as y14_,
stprodsup3_.FREE_QTY as y15_
from
ST_PRODUCTMASTER this_
left outer join
ST_MEDICINE_CATEGORY medi_cat6_
on this_.CAT_CATEGORY_ID=medi_cat6_.CAT_CATEGORY_ID
left outer join
ST_PRODUCT_MANUFACTURER stprodman1_
on this_.PRODUCT_ID=stprodman1_.PRODUCT_ID
and (
stprodman1_.PROD_MAN_STATUS=?
)
left outer join
ST_MANUFACTURER stman2_
on stprodman1_.MAN_ID=stman2_.MAN_ID
left outer join
ST_PRODUCT_RATES zstpr5_
on this_.PRODUCT_ID=zstpr5_.PRODUCT_ID
and (
zstpr5_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
)
left outer join
ST_PRODUCT_SUPPLIER stprodsup3_
on this_.PRODUCT_ID=stprodsup3_.PRODUCT_ID
and (
stprodsup3_.PROD_SUPPLIER_STATUS=?
)
left outer join
ST_SUPPLIER stsup4_
on stprodsup3_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
inner join
ST_TAX_MASTER tax7_
on this_.TAX_ID=tax7_.TAX_ID
inner join
ST_UNIT unit8_
on this_.UNIT_ID=unit8_.UNIT_ID
where
(
this_.PRODUCT_DELETED <> 'DELETED'
)
and this_.PRODUCT_STATUS=?
zstpr5_ is generated before stsup4_
and thus zstpr5_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
is not accessible
left outer join
ST_PRODUCT_RATES zstpr5_
on this_.PRODUCT_ID=zstpr5_.PRODUCT_ID
and (
zstpr5_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
)
left outer join
ST_PRODUCT_SUPPLIER stprodsup3_
on this_.PRODUCT_ID=stprodsup3_.PRODUCT_ID
and (
stprodsup3_.PROD_SUPPLIER_STATUS=?
)
left outer join
ST_SUPPLIER stsup4_
on stprodsup3_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
ACTUAL EXPECTED ORDER IS
left outer join
ST_PRODUCT_SUPPLIER stprodsup3_
on this_.PRODUCT_ID=stprodsup3_.PRODUCT_ID
and (
stprodsup3_.PROD_SUPPLIER_STATUS=?
)
left outer join
ST_SUPPLIER stsup4_
on stprodsup3_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
left outer join
ST_PRODUCT_RATES zstpr5_
on this_.PRODUCT_ID=zstpr5_.PRODUCT_ID
and (
zstpr5_.SUPPLIER_ID=stsup4_.SUPPLIER_ID
)
Hibernate is generating a number with table name,
1_, 2_ , 3_
even though while creating SQL this order is not maintained,
it is not even created in the order we give.
Since you haven't posted your mapping file, I'll explain how Hibernate orders the joins.
Hibernate uses the mapping xml file to figure out the order of joins, so if you have a relation in it (one-to-many or any other tag) for that table, just move it above the other table's tag.
You can read more about it here.
I'm attempting to get a certain number of rows from the database given a certain user and a max amount. Here is what the code looks like currently:
#Override
public Collection<TestObject> findMaxByUser(User _user, int _max) {
if (_max <= 0) {
throw new IllegalArgumentException("max <= 0: " + _max);
}
Long rowCount = (Long)createCriteria()
.add(Restrictions.eq("m_queryUser", _user))
.setProjection(Projections.rowCount())
.uniqueResult();
Collection<TestObject> results = createCriteria()
.add(Restrictions.eq("m_queryUser", _user))
.setFirstResult(1)
.setMaxResults(_max)
.list();
final int count = rowCount.intValue();
final int totalCount = count > results.size()
? count : results.size();
return results;
This results in a org.hibernate.SQLGrammarException: could not prepare statement error.
The strange thing is, if I change DB implementations to Derby, the code works fine. But there's something goofy happening using H2 when I try to use .setMaxResults(). If I use .setFetchSize() instead it'll return all the results no problem, but going back to .setMaxResults() produced the above error.
Any help/information would be great.
Caused-by trace:
Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "SELECT THIS_.ID AS ID1_0_5_, THIS_.CREATED_ON AS CREATED2_0_5_, THIS_.UPDATED_ON AS UPDATED3_0_5_, THIS_.VERSION AS VERSION4_0_5_, THIS_.FAVORITE_QUERY AS FAVORITE6_0_5_, THIS_.NAME AS NAME5_0_5_, THIS_.USER_KEY AS USER7_0_5_, USERQUERY2_.ID AS ID1_2_0_, USERQUERY2_.CREATED_ON AS CREATED2_2_0_, USERQUERY2_.UPDATED_ON AS UPDATED3_2_0_, USERQUERY2_.VERSION AS VERSION4_2_0_, USERQUERY2_.MAX_RESULTS AS MAX5_2_0_, USERQUERY2_.PROPERTIES AS PROPERTI6_2_0_, USERQUERY2_.QUERY_STRING AS QUERY7_2_0_, USERQUERY2_.USER_KEY AS USER9_2_0_, USERQUERY2_.TARGETS AS TARGETS8_2_0_, EXTUSER3_.EXT_USER AS EXT1_4_1_, EXTUSER3_.CREATED_ON AS CREATED2_4_1_, EXTUSER3_.UPDATED_ON AS UPDATED3_4_1_, EXTUSER3_.VERSION AS VERSION4_4_1_, M_SORTS4_.USER_QUERIES AS USER1_2_7_, QUERYSORT5_.ID AS SORTS2_3_7_, QUERYSORT5_.ID AS ID1_1_2_, QUERYSORT5_.CREATED_ON AS CREATED2_1_2_, QUERYSORT5_.UPDATED_ON AS UPDATED3_1_2_, QUERYSORT5_.VERSION AS VERSION4_1_2_, QUERYSORT5_.ELEMENT_NAME AS ELEMENT5_1_2_, QUERYSORT5_.SORT_ORDER AS SORT6_1_2_, QUERYSORT5_.TYPE AS TYPE7_1_2_, QUERYSORT5_.USER_QUERY AS USER8_1_2_, USERQUERY6_.ID AS ID1_2_3_, USERQUERY6_.CREATED_ON AS CREATED2_2_3_, USERQUERY6_.UPDATED_ON AS UPDATED3_2_3_, USERQUERY6_.VERSION AS VERSION4_2_3_, USERQUERY6_.MAX_RESULTS AS MAX5_2_3_, USERQUERY6_.PROPERTIES AS PROPERTI6_2_3_, USERQUERY6_.QUERY_STRING AS QUERY7_2_3_, USERQUERY6_.USER_KEY AS USER9_2_3_, USERQUERY6_.TARGETS AS TARGETS8_2_3_, EXTUSER7_.EXT_USER AS EXT1_4_4_, EXTUSER7_.CREATED_ON AS CREATED2_4_4_, EXTUSER7_.UPDATED_ON AS UPDATED3_4_4_, EXTUSER7_.VERSION AS VERSION4_4_4_ FROM IES_TEST_SCHEMA.LES_FAVORITES THIS_ LEFT OUTER JOIN IES_TEST_SCHEMA.LES_USER_QUERIES USERQUERY2_ ON THIS_.FAVORITE_QUERY=USERQUERY2_.ID LEFT OUTER JOIN IES_TEST_SCHEMA.LES_USERS EXTUSER3_ ON USERQUERY2_.USER_KEY=EXTUSER3_.EXT_USER LEFT OUTER JOIN IES_TEST_SCHEMA.LES_USER_QUERIES_SORTS M_SORTS4_ ON USERQUERY2_.ID=M_SORTS4_.USER_QUERIES LEFT OUTER JOIN IES_TEST_SCHEMA.LES_QUERY_SORTS QUERYSORT5_ ON M_SORTS4_.SORTS=QUERYSORT5_.ID LEFT OUTER JOIN IES_TEST_SCHEMA.LES_USER_QUERIES USERQUERY6_ ON QUERYSORT5_.USER_QUERY=USERQUERY6_.ID INNER JOIN IES_TEST_SCHEMA.LES_USERS EXTUSER7_ ON THIS_.USER_KEY=EXTUSER7_.EXT_USER WHERE THIS_.USER_KEY=? OFFSET[*] 1 ROWS FETCH NEXT 2 ROWS ONLY "; SQL statement:
select this_.id as id1_0_5_, this_.created_on as created2_0_5_, this_.updated_on as updated3_0_5_, this_.version as version4_0_5_, this_.favorite_query as favorite6_0_5_, this_.name as name5_0_5_, this_.user_key as user7_0_5_, userquery2_.id as id1_2_0_, userquery2_.created_on as created2_2_0_, userquery2_.updated_on as updated3_2_0_, userquery2_.version as version4_2_0_, userquery2_.max_results as max5_2_0_, userquery2_.properties as properti6_2_0_, userquery2_.query_string as query7_2_0_, userquery2_.user_key as user9_2_0_, userquery2_.targets as targets8_2_0_, extuser3_.ext_user as ext1_4_1_, extuser3_.created_on as created2_4_1_, extuser3_.updated_on as updated3_4_1_, extuser3_.version as version4_4_1_, m_sorts4_.user_queries as user1_2_7_, querysort5_.id as sorts2_3_7_, querysort5_.id as id1_1_2_, querysort5_.created_on as created2_1_2_, querysort5_.updated_on as updated3_1_2_, querysort5_.version as version4_1_2_, querysort5_.element_name as element5_1_2_, querysort5_.sort_order as sort6_1_2_, querysort5_.type as type7_1_2_, querysort5_.user_query as user8_1_2_, userquery6_.id as id1_2_3_, userquery6_.created_on as created2_2_3_, userquery6_.updated_on as updated3_2_3_, userquery6_.version as version4_2_3_, userquery6_.max_results as max5_2_3_, userquery6_.properties as properti6_2_3_, userquery6_.query_string as query7_2_3_, userquery6_.user_key as user9_2_3_, userquery6_.targets as targets8_2_3_, extuser7_.ext_user as ext1_4_4_, extuser7_.created_on as created2_4_4_, extuser7_.updated_on as updated3_4_4_, extuser7_.version as version4_4_4_ from IES_TEST_SCHEMA.les_favorites this_ left outer join IES_TEST_SCHEMA.les_user_queries userquery2_ on this_.favorite_query=userquery2_.id left outer join IES_TEST_SCHEMA.les_users extuser3_ on userquery2_.user_key=extuser3_.ext_user left outer join IES_TEST_SCHEMA.les_user_queries_sorts m_sorts4_ on userquery2_.id=m_sorts4_.user_queries left outer join IES_TEST_SCHEMA.les_query_sorts querysort5_ on m_sorts4_.sorts=querysort5_.id left outer join IES_TEST_SCHEMA.les_user_queries userquery6_ on querysort5_.user_query=userquery6_.id inner join IES_TEST_SCHEMA.les_users extuser7_ on this_.user_key=extuser7_.ext_user where this_.user_key=? offset 1 rows fetch next 2 rows only [42000-171]
It sounds like you are not using the right dialect...
Double check what it is set to.
hibernate.dialect=org.hibernate.dialect.H2Dialect
i doing some project using Java(netbeans sw) and link to Microsoft Access.
The problem occur when i need to inner join 3 tables together from Microsoft Access,
i have no problem to inner join 2 tables together
rsUpdate =
stmtUpdate.executeQuery("SELECT * FROM A_User Inner Join A_PC ON A_USER.SN = A_PC.SN");
which i able to get the result. But not inner join with 3 tables
rsUpdate =
stmtUpdate.executeQuery
("SELECT * FROM A_User Inner Join A_CPU ON A_USER.SN = A_CPU.SN , Inner Join A_Software ON A_CPU.SN = A_Software.SN")
For the SQL above I have 3 "A" table separately for USER | CPU | Software|
USER PK is SN | CPU FK is SN | Software PK is SN |
The Error I got java.sql.SQLException:Characters found after end SQL statement
Thanks
rsUpdate =
stmtUpdate.executeQuery
("SELECT * FROM A_User
Inner Join A_CPU ON A_USER.SN = A_CPU.SN
Inner Join A_Software ON A_CPU.SN = A_Software.SN");
no need for ',' here... try this above code
For Ms Access, when you JOIN more than table, the syntax is different. It should be this way:
SELECT *
FROM ((a_user
INNER JOIN a_cpu
ON a_user.sn = a_cpu.sn)
INNER JOIN a_software
ON a_cpu.sn = a_software.sn)
There should be no comma after the first join
rsUpdate =
stmtUpdate.executeQuery
("SELECT * FROM A_User Inner Join A_CPU ON A_USER.SN = A_CPU.SN Inner Join A_Software ON A_CPU.SN = A_Software.SN")
Problem Solved
For example -
Table A | Username(PK)| Address|
Table B | ID | Phone | Username(FK)|
Table C | SN | Brand | Model | Username(FK)
rs = st.executeQuery
("SELECT * FROM (A Inner Join B on A.Username = B.Username) Inner Join C on A.Username = C.Username");
if anyone looking for inner join 3 tables together by Using JAVA and Link to Access
use the referenece above.
Make sure you must link the table relationship in Access before run the java program if not it will pop out "ERROR IN ROW"
Thanks everyone who helping me :)