Getting all pending requests one to many mappings

Alex Man :

I have two tables (requests and requests_details) like as shown below. requests table have request_id and request name and requests_details have the details whether the request is in pending, approved or rejected. I have implemented the below two tables in one to many mapping using Spring JPA. In requests_details table if there is second entry apart from PENDING status for a request then it means from the status we can know if the request is approved or a rejected one

Now I have a requirement to get all the pending and approval requests separately

I have wrote the hql query like as shown below

For getting all the pending requests

SELECT request.name, details.* 
FROM requests request JOIN request_details details ON request.request_id=details.request_id 
WHERE 
details.status = "PENDING" AND 
details.status !="APPROVED" OR details.status !="REJECTED"

but for the above query it is returning all the requests

For getting all the approved requests

SELECT request.name, details.* 
FROM requests request JOIN request_details details ON request.request_id=details.request_id 
WHERE 
details.status = "PENDING" AND 
details.status ="APPROVED"

but for the above query it is not returning any requests

enter image description here

My expected result is as give below

enter image description here

enter image description here

Can anyone please help me on this

Norbert Bicsi :

What is happening in the first query is that you are stating that the status should be "PENDING" and not "APPROVED" (this covers "REJECTED") or not "REJECTED" (this covers all other cases) that is why you get everything.

If you are trying to get all "PENDING" then just simply

SELECT
  request.id,
  details.*
FROM requests request
  JOIN request_details details ON request.request_id = details.request_id
WHERE details.status = "PENDING"
AND (SELECT count(*) FROM requests_details
     WHERE requests_details.request_id = request.request_id) = 1

The subquery makes sure there is only one entry for the request meaning it is only "PENDING" and has not be approved or rejected.


In the second case you are getting nothing back because you are stating that the status should be "PENDING" and "APPROVED" at the same time and that will always be false.

If you want to get entries that are both "PENDING" and "APPROVED" then you can do something like this

SELECT
  request.request_id,
  details.*
FROM requests request
  JOIN requests_details details ON request.request_id = details.request_id
WHERE details.status = 'PENDING'
  AND (SELECT count(*) FROM requests_details
         WHERE requests_details.request_id = request.request_id
           AND requests_details.status = 'APPROVED'
      ) = 1

What happens is that you find all "PENDING" requests and then make sure those are also "APPROVED". This is done with the subquery. There you only need to know that the record with the right id and the "APPROVED" status exists, that is why you would use the count, the data you already have from the previous part.


NOTE: It would be a good idea to update the status of requests from "PENDING" to "APPROVED" or "REJECTED" rather than inserting a new record. This would be safer and queries would be more simple and faster (you wouldn't need the subquery). It would also avoid possible bugs where requests end up having multiple conflicting statuses.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=101414&siteId=1