How to add complex inner query to #Query annotaion - spring-data-jpa

normal sql query which work correctly in db in sql developer passing values for bID and period.
SELECT * FROM A WHERE abcID IN (SELECT abcID FROM B WHERE bID=1) AND period=3
in project at Repository class I passed as this
#Query("select a from A where a.abcID IN:(select b.abcId from B where bID=:RevID) and period=:period")
error comes as
Space is not allowed after parameter prefix ':' [select a from A
where a.abcID IN:(select b.abcId from B where bID=:RevID) and
period=:period]
I want to know how should I insert above query correctly in #Query annotation

First of all I would tell you below points.
you can't use select query as select a from A where a.abcID. Here a is a column so can't define something like a.abcID. It need to be select column from tableA a where a.abcID
Same for query use in IN clause. It needs to be like select b.abcId from tableB b where b.bID=:RevID
What you use as :RevID, :period need to be passed as #Param("RevID"), #Param("period") to the query method.
This is the query template.
#Query("select a.nameOfcolumnYouWantToRetrieve from tableA a where a.someColumn in(select b.someColumn from tableB b where b.columnValueOfTableBYouwantToMatch=:RevID) and a.period=:period")
Using this points, try below query.
#Query("select a.id from A a where a.abcID in(select b.abcId from B b where b.bID =:RevID) and a.period=:period")

Related

select table.object_type and select table.* don't return the same value for object_type

I'm trying to select all the 'Application Functions' linked to an object. So I've read the following query:
select
other.ea_guid as CLASSGUID, other.object_type as CLASSTYPE,
obj.name,
other.*
from t_object as obj
join (
select t_connector.start_object_id as Object2_id, t_object.* from t_object
join t_connector on t_connector.end_object_id=t_object.Object_id
where t_object.object_type = 'Application Function'
union
select t_connector.end_object_id as Object2_id, t_object.* from t_object
join t_connector on t_connector.start_object_id=t_object.Object_id
where t_object.object_type = 'Application Function'
) as other on obj.Object_id=other.Object2_id
where obj.object_id = 143299
And it is empty.
Without the where clause, it returns:
But if I change in the select the other.* by named columns like other.object_type, object_name then column obj.namegets empty and other.object_typeas another value:
I thing this difference explains why my select doesn't work. But how to explain and resolve this ?
EA does some special magic to some of the fields when returned by a query.
It does so based on the exact name of the returned field such as Object_Type or Note
To avoid this make sure to give those fields a different alias. e.g. Object_Type as theRealType
In this case I'm going to assume you are looking for ArchiMate application functions. The fact that this is an Application function is actually stored in the Stereotype rather than the Object_Type
A query like this should return all ArchiMate Application Functions linked to an object with id 143299
select o2.Object_ID AS CLASSGUID, o2.Object_Type AS CLASSTYPE, o2.Object_Type as theRealObjectType,
o2.*
from t_object o
inner join t_connector c on c.Connector_ID in (c.Start_Object_ID, c.End_Object_ID)
inner join t_object o2 on o2.Object_ID in (c.Start_Object_ID, c.End_Object_ID)
and o2.Object_ID <> o.Object_ID
where o.Stereotype = 'ArchiMate_ApplicationFunction'
and o2.Object_ID = 143299
This query has been written and tested on an SQL Server repository. It might need tweaking if you want to use it on a .eap file (MS Access SQL Syntax)

JPA query returning a Tuple where one part is an Entity

I have two unrelated tables that I want to do an LEFT JOIN on, I only want 1 column from the LEFT table but the entire entity (which I intend to update if its present or create if not) from the right.
Simplified version of tables:
TABLE1
id, type, data
TABLE2
id, type, and, other, stuff
Current JPQL:
SELECT T1.type,
(SELECT T2
FROM TABLE2 T2
WHERE T2.id = T1.id
AND T2.type = T1.type)
FROM T1
WHERE T1.id = :ID
I am currently getting some sort of logical union error...
Can this been done or should I just use separate queries?
The exact exception is:
Caused by: java.lang.ClassCastException: org.apache.openjpa.jdbc.sql.LogicalUnion$UnionSelect incompatible with org.apache.openjpa.jdbc.sql.SelectImpl
The Java code I use follows:
Query q = this.em.createQuery(jql, Tuple.class);
q.setParameter("ID", id);
#SuppressWarnings("unchecked")
List<Tuple> result = q.getResultList();
The subquery is not essential to my solution - it's just the only form that was parseable - a regular SQL LEFT JOIN wasn't. In words what I am trying to do is for a given ID in TABLE1 find all rows in TABLE2 that have the same ID and type or null if there is no row. Later code will create rows in TABLE2 where there are none for the id and type. I'm expecting 2-3 types per ID in TABLE1 and about half the time for a matching row in TABLE2.

Pentaho DI - How to use "all" results from prior step in the next step as an "IN" query

I have input from a tableA in database A that I would like to join to another tableB in database B.
These were my two options:
Use Database Join: For each input from table in database A, run the
join query in database B.
Use two Input tables (talbeA + tableB) and do merge join on key.
I went with option #1 as I want to avoid reading in tableA and tableB in entirety.
My question is:
How can I use all results from a prior step as one "IN" query?
For instance
select *
from tableB b
where b.id IN (all_rows_from_prior_step)
versus (where it runs for each input row)
select *
from tableB b
where b.id = ?
Use 'Group by' to flatten the rows into one row with a field 'all_rows_from_prior_step' of comma separated ids (Group field: empty, Name: all_rows_from_prior_step, Subject: id, Type: 'Concatenate strings separated by ,'). Next, use a 'User Defined Java Expression' to build the sql query:
"select * from tableB b where b.id IN (" + all_rows_from_prior_step + ")"
Last, use 'Dynamic SQL row' to run the query. The template sql could be
select * from tableB b where 1=0

Postgres is value in column

I have two tables A and B. B includes a column binder which contains integers. Now I want to search those rows of table A which are in placed in A.binder. The following statement does what I want:
SELECT * FROM A WHERE A.binder=ANY(SELECT binder FROM B)
But I expected something like
SELECT * FROM A WHERE A.binder=ANY(B.binder)
or
SELECT * FROM A WHERE A.binder IN array_agg(B.binder)
would work. Consider B.binder could contain duplicates. Therefor I cant simplify the statement by using inner join.
An INNER JOIN is still possible.
SELECT A.* FROM A INNER JOIN (SELECT DISTINCT binder FROM B) AS C ON
A.binder = C.binder
Why doesn't ANY(B.binder) work? because ANY in this context expects a subquery.
Use a subquery to get your integers from table B.
SELECT * FROM A
WHERE A.binder IN (
SELECT binder FROM B
);

How do you add join a table using Criteria class?

I am new to using Criteria, and i am trying to join tables on my query.
This is my expected query set up
Select * FROM ATable a INNER JOIN BTable b ON a.id = b.fk_id WHERE fk_pname = ":cat";
Do you know how i can add the "INNER JOIN BTable b ON a.id = b.fk_id"?
I already added in instance, but not sure how to add the other table.
Criteria criteria = this.getSession().createCriteria(ATable.class);
Thanks again for all your help
Something like this will do it -
Criteria criteria = this.getSession().createCriteria(ATable.class)
.createAlias("btable","b")
.add(Restrictions.eq("b.pname",":cat")
The string 'btable' refers to the property name in the ATable entity class that corresponds to the BTable entity.