table1 |
---|
tasknum |
description |
refid |
sysdesc |
table2 |
---|
tasknum |
stepno |
stepdetail |
approvaldate |
table3 |
---|
id |
startdate |
enddate |
SELECT
t1.tasknum
, t1.description
, t1.refid
, t1.sysdesc
, t2.stepno
, t2.stepdetail
, t2.approvaldate
, MIN(t3.startdate) AS min_date1
, MIN(t3.enddate) AS min_date2
FROM TABLE1 t1
LEFT OUTER JOIN TABLE2 t2 ON t1.tasknum = t2.tasknum
AND t2.stepno = (
SELECT MIN(stepno)
FROM TABLE2
WHERE tasknum = t2.tasknum
)
LEFT OUTER JOIN TABLE3 t3 ON t1.refid = t3.id
WHERE t1.sysdesc LIKE 'Apple'"""
GROUP BY
t1.tasknum
, t1.description
, t1.refid
, t1.sysdesc
, t2.stepno
, t2.stepdetail
, t2.approvaldate
table1
tasknum | description | refid | sysdesc |
---|---|---|---|
1 | Australia | 1 | Apple |
2 | India | 2 | Apple |
3 | West Indies | 3 | Orange |
4 | Cambodia | 4 | Apple |
table2
tasknum | stepno | stepdetail | approval date |
---|---|---|---|
1 | 10 | Start | 1-Apr |
1 | 20 | Review | 2-Apr |
1 | 30 | In Work | 5-Apr |
1 | 40 | Release | |
1 | 50 | Close | |
2 | 10 | Start | 1-Apr |
2 | 20 | Review | |
2 | 30 | In Work | |
2 | 40 | Release | |
2 | 50 | Close |
table3
id | startdate | enddate |
---|---|---|
1 | 3/8/2025 | 4/9/2025 |
1 | 3/9/2025 | 4/5/2025 |
1 | 3/10/2025 | 4/9/2025 |
2 | 3/11/2025 | 4/12/2025 |
3 | 3/12/2025 | 4/13/2025 |
3 | 3/13/2025 | 4/12/2025 |
Conditions:
stepno
, stepdetail
for given tasknum
without approval date for each tasknum
tasknum
with approval date for each tasknum
Sample output required is shown below for tasknum = 1
:
tasknum | description | refid | sysdesc | stepno | stepdetail | approval date | startdate | enddate |
---|---|---|---|---|---|---|---|---|
1 | Australia | 1 | Apple | 40 | Release | 5-Apr | 3/8/2025 | 4/5/2025 |
Please find the fiddle which is working but not returning results as expected.
Fiddle gives result of what I have accomplished but it is giving incorrect results.
I'm unable to address conditions 2 & 3 mentioned.
In your current query you have to differentiate the "approved" from the "non approved" dates,
thus have two tables instead of t2
, each one with its dedicated criteria (AND approvaldate IS NULL
/ AND approvaldate IS NOT NULL
).
…
LEFT OUTER JOIN TABLE2 t2 ON t1.tasknum = t2.tasknum
AND t2.stepno = (
SELECT MIN(stepno)
FROM TABLE2
WHERE tasknum = t2.tasknum
AND approvaldate IS NULL -- ← This line added to t2
)
LEFT OUTER JOIN TABLE2 tapp ON t1.tasknum = tapp.tasknum
AND tapp.stepno = (
SELECT MAX(stepno)
FROM TABLE2
WHERE tasknum = t2.tasknum
AND approvaldate IS NOT NULL
)
…
(see it integrated with your data and the rest of your query (first query))
… But I would suggest that you directly reduce your joins of t2
, t3
and tapp
to 1-row (per t1.id
), instead of double-joining to them (once to get the min / max, once to select the complete row corresponding to this min / max), so that you don't even have to puzzle on "do I need a GROUP BY
or not?".
MIN()
for t3
)stepdetail
corresponding to the highest stepno
"), use an ORDER BY stepno
and limit the resultset to 1 using TOP 1
SELECT
ed columnSELECT
t1.tasknum
, t1.description
, t1.refid
, t1.sysdesc
, t2.stepno
, t2.stepdetail
, (
SELECT TOP 1 approvaldate -- Or SELECT MAX(approvaldate) with no ORDER BY, depending if we want the "latest approval" or "approval of the most advanced step" (which probably are the same, but what to do when they are not?), see @charlieface's comment.
FROM TABLE2
WHERE TABLE2.tasknum = t1.tasknum
AND TABLE2.approvaldate IS NOT NULL
ORDER BY stepno DESC
) AS approvaldate
, t3.min_date1
, t3.min_date2
FROM TABLE1 t1
OUTER APPLY
(
SELECT TOP 1 stepno, stepdetail
FROM TABLE2
WHERE TABLE2.tasknum = t1.tasknum
AND TABLE2.approvaldate IS NULL
ORDER BY stepno
) t2
OUTER APPLY -- Or CROSS APPLY if we want to discard tasks with no step approved yet, see @charlieface's comment.
(
SELECT MIN(startdate) min_date1, MIN(enddate) min_date2
FROM TABLE3 t3
WHERE t1.refid = t3.id
) t3
WHERE t1.sysdesc LIKE 'APPLE';
(running as the second query of the fiddle)