I am trying to run few SQL queries using Java Spark libraries.
All SQLs are running fine except one:
(SELECT CMM.BENEFIT, (length(CMM.HIERARCHY) - length(replace(CMM.HIERARCHY,'>','')) + 1) BNFT_CMPNT_LVL_NBR, LBCX.SERVICE_DEF_TGT_CD, LBCX.SERVICE_DEF_DESC, LBCX.BENEFIT_CMPNT_DESC, LBCX.SERVICE_DEF_TGT_CD, CMM.HIERARCHY FROM EHUB_PROD_RAW.cs90_master_mapping CMM INNER JOIN EHUB_PROD_RAW.wpd_spider_benefit_hierarchy WSBH ON CMM.HIERARCHY = WSBH.HIERARCHY INNER JOIN EHUB_PROD_RAW.legacy_bnft_cmpnt_xref LBCX ON CMM.BENEFIT = LBCX.BENEFIT_CMPNT_NM)
Same query runs fine from SQL Developer!
I am guessing something with hidden char or quotes.
Any guidance please.
You are selecting the same column twice:
( select
cmm.benefit,
( length(cmm.hierarchy) - length(replace(cmm.hierarchy,'>','') ) + 1 ) bnft_cmpnt_lvl_nbr,
lbcx.service_def_tgt_cd,
lbcx.service_def_desc,
lbcx.benefit_cmpnt_desc,
--lbcx.service_def_tgt_cd, <-- this one is duplicated
cmm.hierarchy
from
ehub_prod_raw.cs90_master_mapping cmm
inner join ehub_prod_raw.wpd_spider_benefit_hierarchy wsbh on cmm.hierarchy = wsbh.hierarchy
inner join ehub_prod_raw.legacy_bnft_cmpnt_xref lbcx on cmm.benefit = lbcx.benefit_cmpnt_nm
)
If you need it twice in the result set, then you should use aliases. I think SQL Developer will auto-alias it by appending a _1 to one of the ambiguous columns.
Related
I tried to use querydsl from java code. but when using inner query with more the on column in select clause, I cant approach to specified columns. r.maxTime for example.
FROM (
SELECT Train, MAX(Time) as MaxTime
FROM TrainTable
GROUP BY Train
) r
INNER JOIN TrainTable t
ON t.Train = r.Train AND t.Time = r.MaxTime
I have defined my models in JPA and am writing some queries for my application and I am using JOOQ generated classes to join all the tables together to check if the requested resources actually belong to the requesting user.
However, when I do this I get the following warning:
Ambiguous match found for ID. Both "alias_4548634"."ID" and "alias_47496750"."ID" match.
java.sql.SQLWarning: null
at org.jooq.impl.Fields.field(Fields.java:132) ~[jooq-3.11.10.jar:?]
... etc
This is my code
db.select(countField)
.from(thing)
.where(JThing.THING.thingBucket().bucket().organization().customer().ID.in(idList))
.orderBy(countField)
This is the SQL it generates
SELECT
count(PUBLIC.THING.ID) AS count
FROM (
PUBLIC.THING
LEFT OUTER JOIN (
PUBLIC.THING_BUCKET AS alias_72652126
LEFT OUTER JOIN (
PUBLIC.BUCKET AS alias_4548634
LEFT OUTER JOIN (
PUBLIC.ORGANISATION AS alias_43016761
LEFT OUTER JOIN PUBLIC.CUSTOMER AS alias_47496750
ON alias_43016761.CUSTOMER_ID = alias_47496750.ID
)
ON alias_4548634.ORGANISATION_ID = alias_43016761.ID
)
ON alias_72652126.ID = alias_4548634.ID
)
ON PUBLIC.THING.THING_BUCKET_ID = alias_72652126.ID
)
WHERE alias_47496750.ID IN (81353)
ORDER BY count
Given that JOOQ is generating the SQL I'd expect it to be able to understand it without throwing an error. What am I missing? How do I do configure/query/whatever to resolve the SQLWarning?
UPDATE
After playing around I've identified the source of the issue.
THING_BUCKET is sub-type of BUCKET so that THING_BUCKET.ID = BUCKET.ID
if I rewrite the query to I get the same results, but without the error
SELECT
count(PUBLIC.THING.ID) AS count
FROM (
PUBLIC.THING
LEFT OUTER JOIN (
PUBLIC.BUCKET AS alias_4548634
LEFT OUTER JOIN (
PUBLIC.ORGANISATION AS alias_43016761
LEFT OUTER JOIN PUBLIC.CUSTOMER AS alias_47496750
ON alias_43016761.CUSTOMER_ID = alias_47496750.ID
)
ON alias_4548634.ORGANISATION_ID = alias_43016761.ID
)
ON PUBLIC.THING.BUCKET_ID = alias_4548634.ID
)
WHERE alias_47496750.ID IN (81353)
ORDER BY count
So what I would like to be able to do is go
db.select(countField)
.from(thing)
.where(JThing.THING.bucket().organization().customer().ID.in(idList))
.orderBy(countField)
and join my THING directly to the BUCKET rather then the THING_BUCKET, but I do not know how to accomplish this with the generated classes.
This looks like a bug that has been fixed in jOOQ 3.14, see #8659, #10603
From your description, looks like BUCKET and THINK_BUCKET being described as subtypes in the db level, are getting confused by the jooq generated classes.
A short term fix may be, to cut the hierarchical relation in the db level, regenerate and see what happens.
so tried to put that SQL code into my java-aplication:
SELECT DISTINCT
StRzImRo.Rohstoff, StRo.Bezeichnung,
CAST (SUM(BwLsImAt.Lieferungen * StRzImRo.Menge * StAt.PROD__REZEPTURGEWICHT / Coalesce(StRz.PARM__BEZUGSGROESSE,1)) AS NUMERIC (9,3)) Rohstoffverbrauch_Gesamt FROM BwLsImAt
JOIN StAt ON (StAt.IntRowId = BwLsImAt.Artikel)
JOIN StRz ON (StRz.IntRowId = StAt.PROD__REZEPTUR)
JOIN StRzImRo ON (StRzImRo.Master = StRz.IntRowId)
JOIN StRo ON (StRzImRo.Rohstoff = StRo.IntRowId)
WHERE StAt.IntRowId > 0
GROUP BY StRzImRo.Rohstoff, StRo.Bezeichnung
-- GROUP BY StRzImRo.Rohstoff, StRzImRo.Menge, StAt.PROD__REZEPTURGEWICHT, Coalesce(StRz.PARM__BEZUGSGROESSE,1)
The code is fully funcional and tested in IBSQL but not working in my java-application.
My app does work properly with other code. I get this error:
org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544569. Dynamic SQL Error
SQL error code = -104
Token unknown - line 1, column 266
ON
I would be very happy if someone could help me with this problem. Thanks!
P.S.: Sorry for my bad language, but i´m not a native speaker
The error suggests there is an ON in an unexpected place in your query, and as the query itself looks fine, my guess is the problem is with the way you construct the query in your Java application. There might be some whitespace missing in your query.
My guess is that you have something like
query = "SELECT * " +
"FROM table1" +
"JOIN table2 ON " //.....
The missing whitespace will make the SQL:
SELECT * FROM table1JOIN table2 ON ....
For the parser, this is perfectly valid until it encounters the ON token, which triggers the error. Eg the parser identifies it is a SELECT with * (all) columns from table1JOIN with alias table2. During parsing the server doesn't check if the table actually exists, so it doesn't trip over the fact that table1JOIN doesn't exist. That is checked after parsing is successfully completed.
I facing with a strange situation with a sql query on mysql 5.1.41 environment on a Ubuntu machine.
The code follow
SELECT spedizione0_.idspedizione,
spedizione0_.*,
(
SELECT COUNT(n.idnegozio)
FROM negozio n
LEFT JOIN confezione c
ON n.idnegozio = c.idnegozio
AND c.idspedizione = spedizione0_.idspedizione
WHERE n.datainizio <= spedizione0_.dataspedizione
AND n.datafine >= spedizione0_.dataspedizione
OR c.idspedizione != 0
) AS formula5_
FROM orocashgenerico.spedizione spedizione0_
ORDER BY spedizione0_.dataspedizione DESC
In this case the error says : [Err] 1054 - Unknown column 'spedizione0_.idspedizione' in 'on clause'
The only way to run this query is to change the .. on n.idnegozio=c.idnegozio and c.idspedizione=spedizione0_.idspedizione into on n.idnegozio=c.idnegozio and c.idspedizione=12
The most strange things for me is: if i move the and condition to the where clause the query run correctly, of course the results is not what I excepted.
My question is where is the problem?
Is something related to the MySQL version?
It's because spedizione0_ is not found with the scope of your subquery. Try this one,
SELECT spedizione0_.idspedizione, // add additionl columns
COUNT(n.idnegozio) AS formula5_
FROM spedizione spedizione0_
LEFT JOIN confezione c
ON c.idspedizion = spedizione0_.idspedizione
LEFT JOIN negozio n
ON n.idnegozio = c.idnegozio
WHERE (
n.datainizio <= spedizione0_.dataspedizione AND
n.datafine >= spedizione0_.dataspedizione
)
OR c.idspedizione != 0
GROUP By spedizione0_.idspedizione
ORDER BY spedizione0_.dataspedizione DESC
as I can see, you are using the wrong syntax here. When you use a Left Outer join, you cannot mention more than one condition in ON clause.
In your case, you need to use one more Left join clause after that ON clause to join 3rd table which is giving error.
I'm using Hibernate. I wrote some native query because I need to use sub select statement.
Query looks like this:
SELECT sub.rownum FROM
(SELECT k.`news_master_id` AS id, #row := #row + 1 AS rownum
FROM keyword_news_list k
JOIN (SELECT #row := 0) r
WHERE k.`keyword_news_id` = :kid
ORDER BY k.`news_master_id` ASC) AS sub
WHERE sub.id = :nid
When I run this query like this:
sessionFactory.getCurrentSession()
.createSQLQuery(query)
.setParameter("kid", kid)
.setParameter("nid", nid)
.uniqueResult();
This exception comes out:
org.hibernate.QueryException: Space is not allowed after parameter prefix ':' ....
This might because of := operator. I found some Hibernate issue about this. This issue is still open. Isn't there any solution for this problem?
Note that HHH-2697 is now fixed for Hibernate 4.1.3 You can now escape with backslash:
SELECT k.`news_master_id` AS id, #row \:= #row + 1 AS rownum
FROM keyword_news_list k
JOIN (SELECT #row \:= 0) r
WHERE k.`keyword_news_id` = :kid
ORDER BY k.`news_master_id` ASC
Another solution for those of us who can't make the jump to Hibernate 4.1.3.
Simply use /*'*/:=/*'*/ inside the query. Hibernate code treats everything between ' as a string (ignores it). MySQL on the other hand will ignore everything inside a blockquote and will evaluate the whole expression to an assignement operator.
I know it's quick and dirty, but it get's the job done without stored procedures, interceptors etc.
you can implement this is a slightly different way.. you need to replace the : operator with something else (say '|' char ) and in your interceptor replace the '|' with the : .
this way hibernate will not try to think the : is a param but will ignore it
For the interceptor logic you can refer to the hibernate manual
This has worked for me using MySQL 5.
remember, this replacing of : must be only done to ':=' and other MySQL specific requirments.. don't try to replace the : for the param-placeholders. (hibernate will not be able to identify the params then)
I prefer to include Spring JDBC and execute the query rather than fight against Hibernate interceptors.
in Hibernate exception on encountering mysql := operator Stanislav gave another option other than interceptor to solve this issue
If you keep your SQL-files away from Java code - try this piece of code. Played a lot to get the right number of escaping slashes:
String sqlPattern = FileUtils.readFile(this.getClass(), /sql/my_query.sql");
sqlPattern = sqlPattern.replaceAll(":=", "\\\\:=");
Query query = entityManager.createNativeQuery(sqlPattern);
I guess there should not be a space after = , the operator should be written as =: (without any spaces)