I have one table (table1) with columns:
ID | NAME |
---|---|
1 | A |
2 | B |
3 | C |
4 | D |
and another table (table2) with columns:
ID | table1.ID | DATE | STATUS |
---|---|---|---|
1 | 1 | 21-JUL-2020 | INACTIVE |
2 | 1 | 22-JUL-2022 | ACTIVE |
3 | 1 | 23-JUL-2022 | ACTIVE |
4 | 2 | 21-JAN-2022 | ACTIVE |
5 | 2 | 22-JAN-2022 | INACTIVE |
6 | 2 | 23-JAN-2022 | ACTIVE |
7 | 3 | 20-JAN-2022 | INACTIVE |
8 | 3 | 20-JAN-2022 | INACTIVE |
I am trying to write a query that will return distinct rows from table1 where status from table2 is ACTIVE
and results should be ordered by min DATE from table2.
Desired result:
ID | NAME |
---|---|
2 | B |
1 | A |
I tried with the following:
select t1, min(t2.date)
from table1 t1 join t1.t2List t2 -- table1 Entity has OneToMany t2List defined
where t2.status = 'ACTIVE'
group by t1.id
order by t2.date desc;
Problem here is that I can't use my Entity class table1 and I would like to avoid creating a new class that will hold this additional aggregated result (min date).
Also tried using HAVING clause but could not get it working.
select t1 from table1 t1
where t1.id in (
select table1.id from table2 t2 where t2.status = 'ACTIVE'
group by t1.id, t2.date
having t2.date = min(t2.date));
Appriciete any help here!
CodePudding user response:
Join table1
to a query that aggregates in table2
and returns all table1_id
s with an ACTIVE
row:
SELECT t1.*
FROM table1 t1
INNER JOIN (
SELECT table1_id, MIN(date) date
FROM table2
WHERE status = 'ACTIVE'
GROUP BY table1_id
) t2 ON t2.table1_id = t1.id
ORDER BY t2.date;
See the demo.
CodePudding user response:
There are multiple ways of solving this problem, as @forpas has already answered using a subquery in the JOIN clause.
The same results can be achieved using this query
SELECT table1.ID , table1.name
FROM table1
INNER JOIN table2 ON table2.table1_ID = table1.ID
WHERE status = 'ACTIVE'
GROUP BY table1.ID , table1.name
ORDER BY MIN(table2.statusDate)