UNION in MySQL using JDBC - java

I have problem when using UNION problem: I have 2 tables TOPIK and SUBTOPIK which I do left join and right join then make union of them using the following statement:
mySqlStmt = "SELECT *
FROM TOPIK
LEFT OUTER JOIN SUBTOPIK
ON TOPIK.IDTOPIK=SUBTOPIK.IDTOPIK
WHERE (TOPIK.TARGETNPMHS LIKE '%0000312100006%'
OR ((TOPIK.TARGETOBJECTNICKNAME LIKE '%OPERATOR KEPALA BAA%'
OR TOPIK.TARGETOBJECTNICKNAME LIKE '%OPERATOR BAA%' )
AND TOPIK.TARGETNPMHS IS NULL))
UNION
SELECT *
FROM TOPIK
RIGHT OUTER JOIN SUBTOPIK
ON TOPIK.IDTOPIK=SUBTOPIK.IDTOPIK
WHERE (SUBTOPIK.NPMHSRECEIVER LIKE '%0000312100006%'
OR ((SUBTOPIK.OBJNICKNAMERECEIVER LIKE '%OPERATOR KEPALA BAA%'
OR SUBTOPIK.OBJNICKNAMERECEIVER LIKE '%OPERATOR BAA%' )
AND SUBTOPIK.NPMHSRECEIVER IS NULL))"
The code above works on mysql workbench, but when i use it in java,
get connection...bla..bla;
stmt = con.prepareStatement("mySqlStmt");
rs = stmt.executeQuery();
while(rs.next()) {
String topik_idTopik = ""+rs.getLong("TOPIK.IDTOPIK");
}
i got
java.sql.SQLException: Column 'TOPIK.IDTOPIK' not found.
but both TOPIK and SUBTOPIK have this column.

The column's alias is IDTOPIK, you should not use the fully qualified name:
stmt = con.prepareStatement(mySqlStmt);
rs = stmt.executeQuery();
while(rs.next()) {
String topik_idTopik = ""+rs.getLong("IDTOPIK");
}

Your where clause undoes the right outer join. You might as well do:
SELECT *
FROM TOPIK t LEFTJOIN
SUBTOPIK s
ON t.IDTOPIK = s.IDTOPIK
WHERE (s.NPMHSRECEIVER LIKE '%0000312100006%' OR
(s.OBJNICKNAMERECEIVER LIKE '%OPERATOR KEPALA BAA%' OR
s.OBJNICKNAMERECEIVER LIKE '%OPERATOR BAA%'
) AND
s.NPMHSRECEIVER IS NULL
)
);
Of course, the problem you have is with the alias, not the join, but you might as well have a correct query.

Related

JQPL select inside select

just switched to spring boot from .NET Core, in .NET core we can easily nest a select inside a select like this:
var result = from c in context.Cars
join br in context.Brands
on c.BrandId equals br.Id
join col in context.Colors
on c.ColorId equals col.Id
select new CarDetailDto
{
Id = c.Id,
BrandName = br.Name,
CarName = c.Name,
ColorName = col.Name,
DailyPrice = c.DailyPrice,
ModelYear = c.ModelYear,
CarImages = (from cimg in context.CarImages
where cimg.CarId == c.Id
select new CarImage
{
Id = cimg.Id,
ImagePath = cimg.ImagePath,
CarId = c.Id,
Date = cimg.Date
}).ToList()
};
I want to do that in JPQL as well but didnt manage to solve
#Query( select column1, column2, column3 from tablename1 where coluname=(select columname from tablename2 where columnname=abcd) )
Your JPQL query should look like above.
Whatever subquery you write with condition.
If your query is fetching 3 column you need to create a DTO with same column name.
If your query is fetching list of rows then your actual jpql will look like this.
#Query( select column1, column2, column3 from tablename1 where coluname=
(select columname from tablename2 where columnname=abcd) )
List<ResultDTO> findAllResultList(Parameter value);
Above it is mapping the result to list of DTO objects to result rows.
If your query is fetching single row then your actual jpql will look like this.
#Query( select column1, column2, column3 from tablename1 where coluname=
(select columname from tablename2 where columnname=abcd) )
ResultDTO findResult(Parameter value);
The single result is mapped to one DTO object.
Make sure your result column name and DTO column name matches
Using the JPA repository call the names of the method which you used for the particular query.

coalesce mybatis switch case

Iam using coalesce mybatis switch case in my query, where iam getting error like
Error querying database. Cause: java.sql.SQLException: ORA-01427:
single-row subquery returns more than one row
this is my query
(select
(case when (coalesce(t1.col1,t2.col1, t1.col2, t1.col3) is null)
then (select sysdate from dual)
else (coalesce(t1.col1,t2.col1, t1.col2, t1.col3))
end )
from table1 t1
join table2 t2
on t1.id IN (t2.id))
Thanks in advance
Seems you have a lot of () but overall you should use = operator and not IN (t2.id) for join t2.id
select
case when coalesce(t1.col1,t2.col1, t1.col2, t1.col3) is null
then sysdate
else coalesce(t1.col1,t2.col1, t1.col2, t1.col3)
end
from table1 t1
join table2 t2 on t1.id = t2.id
And looking at the code you posted in sample you have a select as a column result and this select return several rows, ( this raise the error). You also have a mixin of join syntax some based on explicit join syntax some based on old implicit join syntax based on comma separated table name and where condition. You should try using this
<select id="Trigger" parameterType="hashmap" resultType="java.util.HashMap" flushCache="true">
SELECT
select case when coalesce(table1.col1, table2.col2,table1.col3, table1.col4) is null
then sysdate
else coalesce(table1.col1, table2.col2,table1.col3, table1.col4) end as "ProgressDate"
, table3.id as "ID"
from table1
INNER join table2 on table1.id = table2.id
INNER JOIN table3 ON table1.id = table3.id
INNER JOIN table4 table2.action = table4.action
WHERE table3.transaction = #{inputvaluepassed}
</select>
The query you mention in the question takes the place of a scalar subquery included in another... main query. I formatted the whole query (for readability) and it looks like this:
SELECT
(
select case when coalesce(table1.col1, table2.col2,table1.col3,
table1.col4) is null
then (select sysdate from dual)
else coalesce(table1.col1, table2.col2,table1.col3, table1.col4)
end
from table1
join table2 on table1.id = table2.id
) as "ProgressDate",
table3.id as "ID"
FROM table3, table1, table2, table4
WHERE table3.transaction = #{inputvaluepassed}
AND table1.id = table3.id
AND table2.id=table1.id and table2.action = table4.action
Now, by definition, scalar subqueries can only return zero or one row. In your case it seems that at runtime this subquery is returning multiple rows, and the main query crashes.
You'll need to somehow produce a single row at most: maybe by aggregating the rows (using GROUP BY), maybe by picking one row only from the result set (using LIMIT); there are other options. If we choose the to limit the rows to 1 at most your query could look like:
SELECT
(
select case when coalesce(table1.col1, table2.col2,table1.col3,
table1.col4) is null
then (select sysdate from dual)
else coalesce(table1.col1, table2.col2,table1.col3, table1.col4)
end
from table1
join table2 on table1.id = table2.id
limit 1 -- added this line
) as "ProgressDate",
table3.id as "ID"
FROM table3, table1, table2, table4
WHERE table3.transaction = #{inputvaluepassed}
AND table1.id = table3.id
AND table2.id=table1.id and table2.action = table4.action
This is just one possible cheap solution to the issue. A better understanding on how to pick the right row over multiples ones can produce a better solution.

I get a column not found exception even if the column exists

I want to execute a query against a MySQL database with Java. The code looks like this:
ResultSet resultSet = statement.executeQuery("select col1 from tb1 inner join tb2 on tb1.col2 = tb2.col3 where col4='"+foo+"'");
The query works perfectly when I use the shell but it doesn't work when I run it with Java because it says that col4 doesn't exist. But col4 exists.
I've just tried something like this;
select col1 from dbname.tb1 as a inner join dbname.tb2 as b on a.col2 = b.col3 where b.col4 = 'foo'
You should call the col4 with the table prefix "tb1" or "tb2".
As example:
select tb1.col1 from tb1 inner join tb2 on tb1.col2 = tb2.col3 where tb1.col4=...
The problem was not there. It was I little bit further:
ResultSet resultSet = statement.executeQuery("select col1 from tb1 inner join tb2 on tb1.col2 = tb2.col3 where col4='"+foo+"'");
myarray.add(resultSet.getString("col4"));//col4 can't exist here because it has not been selected
After executing the query I wanted to access a column that hadn't been selected.

Inner join query on Hibernate - SQL queries do not currently support iteration

I'm new to hibernate and I've this SQL query which works perfectly
SELECT count(*) as posti_disponibili from occupazione t inner join
(select id_posto_park, max(date_time) as MaxDate from occupazione
group by id_posto_park) tm on t.id_posto_park = tm.id_posto_park and
t.date_time = tm.Maxdate and t.isOccupied = 0
which gives me all the last items with isOccupied = 0
I was porting it into Hibernate, I've tried to use
result = ( (Integer) session.createSQLQuery(query).iterate().next() ).intValue()
to return posti_disponibili but i got this exception
java.lang.UnsupportedOperationException: SQL queries do not currently support iteration
How can i solve this? I cannot find the equivalent HQL query
Thank you
I would suggest you to use
Query#uniqueResult()
which will give you single result.
select count(*) .....
will always return you a single result.
Hibernate support it's own iterator-like scroll:
String sqlQuery = "select a, b, c from someTable";
ScrollableResults scroll = getSession().createSQLQuery(sqlQuery).scroll(ScrollMode.FORWARD_ONLY);
while (scroll.next()) {
Object[] row = scroll.get();
//process row columns
}
scroll.close();

Jave SQL executeQuery throws up error for valid sql statement

I am using java java.sql.* for querying from SQLite DB. I found a starnge issue where I write a sqlString as:
SELECT n.Name as Name,
c.Value as Value0,
d.Value as Value1
FROM (Table1 c inner join Table2 n on c.NameID = n.ID),
Table3 d
WHERE c.RunID = 1
and d.RunID = 2
and c.NameID = d.NameID
The statement stmt.executeQuery(sqlQuery) throws the following exception:
java.sql.SQLException: no such column: n.Name
at org.sqlite.DB.throwex(DB.java:288)
at org.sqlite.NativeDB.prepare(Native Method)
at org.sqlite.DB.prepare(DB.java:114)
at org.sqlite.Stmt.executeQuery(Stmt.java:89).............
Name is already part of the Table2 table. The same statement is working fine from SQLite command prompt. But when I remove the open brackets and try to execute from java, there is no problem. Any idea why this happens so?
Try something like this, use sub resultset
SELECT rs1.Name AS NAME,
rs1.Value0 AS Value0,
d.Value AS Value1
FROM (SELECT n.Name AS NAME,
c.Value AS Value0,
d.Value AS Value1
FROM Table1 c INNER JOIN Table2 n ON c.NameID = n.ID) rs1,
Table3 d
WHERE c.RunID = 1
AND d.RunID = 2
AND c.NameID = d.NameID
The variables used in inner queries could not be referred outside. For example, you have used the variable n in inner sql. But you are referring it outside. The variable n is out of it's scope there.
Hi Friends Thanks for your fast responses. I am able to solve this problem. I am sharing this so if any1 else get this problem can do this:
SELECT ABC.Name as Name, ABC.Value as Value0, d.Value as Value1
FROM
(select n.Name as Name, c.Value as Value0 from Table1 c
inner join Table2 n on c.NameID = n.ID) AS ABC,
Table3 d ......;
Regards,Tor

Categories

Resources