I have a table 'Staff' with details of all Staff. 'StaffID' included.
Then I have a table 'StaffRole' which has 'StaffID' and 'RoleID'
I want to do something like this: Select * From Staff Where RoleID=1;
But I'm not sure if I can do this as RoleID is not in the Staff table.
Anyone know the correct syntax? Any feedback is appreciated.
Try this:
SELECT * FROM staff s
WHERE EXISTS(
SELECT 'ROLE'
FROM staffrole r
WHERE r.staffid = s.staffid
AND r.roleid = 1
)
In alternative:
SELECT * FROM staff s
JOIN staffrole r
ON r.staffid = s.staffid
WHERE r.roleid = 1
Use a join:
select s.*
from staffrole r
join staff s
on s.staffid = r.staffid
where roleid = 1
An index on staffrole(roleid) should make it perform better.
Related
I am working on a Spring web application that utilizes hibernate to connect to a DB2 database. I am try to optimize a service method that gets called may times during a wed service call by reducing the number of DB queries.
So my question is whether or not this query
SELECT DISTINCT a.* FROM TABLE_A a
LEFT JOIN TABLE_B b ON a.ID = b.FK_ID
LEFT JOIN TABLE_C c ON a.ID = c.FK_ID
LEFT JOIN TABLE_D d ON c.DATA_RQST_ID = d.ID
WHERE (b.REQUEST_ID = 1234 AND b.TYPE = 'TYPE_A')
OR (c.REQUEST_ID = 1234 AND (c.TYPE = 'TYPE_A' OR c.TYPE = 'TYPE_B'))
is equivalent/better then this query
SELECT * FROM TABLE_A a
WHERE a.ID IN
(
SELECT b.FK_ID FROM TABLE_B b
WHERE b.REQUEST_ID = 1234 AND eb.TYPE = 'TYPE_A'
)
OR a.ID IN
(
SELECT c.FK_ID FROM TABLE_C
WHERE ( c.REQUEST_ID = 1234 AND c.TYPE = 'TYPE_A' )
OR
(
c.TYPE = 'TYPE_B' AND c.REQUEST_ID IN
(
SELECT d.ID FROM TABLE_D d
WHERE d.REQUEST_ID = 1234 AND v.TYPE = 'TYPE_A'
)
)
)
or is there a better option?
Both queries seem to run about the same time (<50ms) but that may depend on the resulting data. I would need to test more to know for sure.
The point of these two queries is for one of them to replace three other queries where their resulting data is processed in Java to get the required data.
I will also have to be able to convert the SQL query to HQL. I was struggling to convert the first query.
I have a feeling that I maybe wasting my time since the java objects for tables B and C are a one-to-many relationship in the object for table A and they are load by hibernate anyway. Meaning I may not be saving anytime in the long run. Is my thinking here correct?
Thanks!
If I understand correctly, exists would be the best solution:
SELECT a.*
FROM TABLE_A a
WHERE EXISTS (SELECT 1
FROM TABLE_B b
WHERE a.ID = b.FK_ID AND b.REQUEST_ID = 1234 AND b.TYPE = 'TYPE_A'
) OR
EXISTS (SELECT 1
FROM TABLE_C c JOIN
TABLE_D d
ON c.DATA_RQST_ID = d.ID
WHERE a.ID = c.FK_ID AND
c.REQUEST_ID = 1234 AND
(c.TYPE IN ('TYPE_A', 'TYPE_B'))
);
One big gain is just in removing the select distinct.
Then for performance, you want indexes on table_b(fk_id, request_id, type_id) and table_c(fk_id, request_id, type, DATA_RQST_ID) and table_d(id).
Can anybody help me to create JPA Criteria Builder query in order to achieve this ?:
select id from (
select distinct r.id
r.date
r.name
from report r
inner join unit u
on u.report_id = r.id
order by
r.date desc,
r.name asc)
where rownum <= 10
I just can create inner query:
CriteriaQuery<Object[]> innerQuery = cb.createQuery(Object[].class);
Root<ReportEntity> root = innerQuery.from(ReportEntity.class);
List<Ojbect[]> resultLsit = em.createQuery(
innerQuery.multiselect(root.get(ReportEntity_.id),
root.get(ReportEntity_.date),
root.get(ReportEntity_.name)
.distinct(true)
.orderBy(cb.desc(root.get(ReportEntity_.date)),
cb.asc(root.get(ReportEntity.name))
).setMaxResults(10).getResultList();
Thx in advance :)
I've decided to get List of Object[] and then retrieve id from array
List idList = resultList.stream().map(array -> (Long)array[0]).collect(Collectors.toList());
This is code smell, but unfortunatelly I haven't found better solution.
Note I use this approach to cope Hibernate issue :
"Warning “firstResult/maxResults specified with collection fetch; applying in memory!”? - this warning pops up due to using fetch and setMaxResults in hql or criteria query.
That's why first of all I get all id, and then I find all entities according this id. (select * from ReportEntity r where r.id in :idList) - smth like this.
Can someone help me?
I got that SQL query and need to represent that in JPQL, but i faced trouble with right join:
SELECT alrt.*
FROM
REACTION.ALERT alrt, REACTION.INVESTIGATION inv,
REACTION.CLASSIFICATION_TYPE clst, REACTION.FRAUD_TYPE frt,
REACTION.TRANS trns, REACTION.CARD crd
WHERE
alrt.ISS_INST IN(1201, 1101) AND
alrt.MODULE_TYPE = 0 AND
0 < (SELECT COUNT(*) FROM REACTION.INVESTIGATION WHERE REACTION.INVESTIGATION.ALERT_ID = alrt.ID) AND
inv.CLASSIFICATION_TYPE_ID IS NOT NULL AND
clst.CLASSIFICATION_TYPE = 10 AND
(alrt.REMINDER_USER_LOGIN = 'qwr' OR alrt.REMINDER_USER_LOGIN IS NULL) AND
alrt.ID = inv.ALERT_ID AND
alrt.TRANSACTION_ID = trns.ID(+) AND inv.CLASSIFICATION_TYPE_ID =
clst.ID AND inv.FRAUD_TYPE_ID = frt.ID(+) AND trns.HPAN = crd.HPAN(+);
After read tutorials and docs i create that JPQL query:
SELECT alrt
FROM INVESTIGATION inv
JOIN inv.CLASSIFICATION_TYPE_ID clst
RIGHT JOIN inv.FRAUD_TYPE_ID frt
JOIN inv.alert_id alrt
RIGHT JOIN alrt.transactio_id trns
RIGHT JOIN trns.HPAN crd
WHERE
alrt.ISS_INST IN(1201, 1101) AND
alrt.MODULE_TYPE = 0 AND 0 < (SELECT COUNT(inv1) FROM INVESTIGATION inv1 WHERE inv1.ALERT_ID = alrt.ID) AND
inv.CLASSIFICATION_TYPE_ID IS NOT NULL AND
clst.CLASSIFICATION_TYPE = 2 AND
(alrt.REMINDER_USER_LOGIN = 'qwr' OR alrt.REMINDER_USER_LOGIN IS NULL);
But i got error then try to execute that. Can someone tell what i did wrong pls?
If it make sense i use JPA 1.0 version
Your error is join ID, but not OR-mapping object.
Try this:
JOIN inv.CLASSIFICATIONTYPE(your mapping property name) clst
If u do not have mapping relationship between entities, u'd better to user join table i.o. OR-mapping.
Read more information on JPQL
My database looks like this
tickets table
-------------
ticket_id
title
description
department_id
status_id
priority_id
assignee_id
creator_id
departments table
------------------
dep_id
dep_name
status table
------------
status_id
status_name
priority table
---------------
pr_id
pr_name
users table
-----------
u_id
username
password
salt
email
firstName
lastName
department_id
userlevel_id
userlevels table
-----------------
ul_id
ul_name
I need to load all tickets given the asignee id. My query looks like this
SQLQuery q = q.createSQLQuery("SELECT t.*,d.*,s.*,p.*,u.*,a.* FROM tickets t, departments d, status s, priority p, users u, attachments a WHERE t.department_id=d.dep_id AND t.status_id=s.stat_id AND t.priority_id=p.pr_id AND t.assignee_id=u.u_id AND t.creator_id=u.u_id AND t.tick_id=a.ticket_id AND assignee_id=?");
q.setInt(0, some_valid_assignee_id);
List<Object> result = q.list();
But it's returning an empty object list. Can anyone point me in the right direction, thanks!!
In your query you have AND t.assignee_id = u.u_idand also AND t.creator_id = u.u_id. The only way that would return any records is if the assignee_id and creator_id were the same. I think what you really need to do is link to the users table twice like so:
SELECT t.*, d.*, s.*, p.*, u1.*, u2.*, a.*
FROM tickets t
INNER JOIN departments d ON t.department_id = d.dep_id
INNER JOIN status s ON t.status_id = s.stat_id
INNER JOIN priority p ON t.priority_id = p.pr_id
INNER JOIN users u1 ON t.assignee_id = u.u_id
INNER JOIN users u2 ON t.creator_id = u.u_id
INNER JOIN attachments a ON t.tick_id = a.ticket_id
WHERE assignee_id = ?
You should use proper join syntax . . . makes the query easier to read and to write.
However, I'm guessing that the problem is:
t.assignee_id = u.u_id AND t.creator_id = u.u_id
That would assume that
t.assignee_id = t.creator_id
Perhaps this never happens in your data.
Hi I need to do the following using Criteria
Select * from product pd, (Select productID pd1 from ... where ...) tpd1,
(Select productID pd2 from ... where ...) tpd2
where pd.productID = tpd1.pd1 and pd.productID = tpd1.pd2
May I know if it is possible?
The original SQL was using IN conditions
Select * from product pd where productID in (Select productID pd1 from ... where ...) and
productID in (Select productID pd2 from ... where ...)
but it takes too long to get the result, using the join SQL statement I was able to obtain my result faster.
any help?
Given you're using Hibernate, you may have to do something like this, which should work ok if the number of expected matches are relatively low:
select *
from product pd
where pd.productID in
(select productID
from product pd2
join tpd1 on (pd2.productID = tpd1.pd1)
join tpd2 on (pd2.productID = tpd2.pd2)
where tpd1....
and tpd2....
);
I assume there is a unique index on product.productID.
Alternatively, you could try the EXISTS formulation which may or may not work better than your original query:
select *
from product pd
where EXISTS
(select null from tpd1 where pd.productID = tpd1.pd1 and ...)
and EXISTS
(select null from tpd2 where pd.productID = tpd2.pd2 and ...)
;