I have a table that has missing information that needs to be inserted with very specific conditions. However, I am unsure on how to proceed.
I have one table that contains an overall view of information. Using Projects as an example
ProjectID | ProjectName |
---|---|
1 | Project A |
2 | Project B |
3 | Project C |
4 | Project D |
I have another table that contains a subset of information of the first table which shows the Statuses and Timeline of those projects.
ProjectStatusID | ProjectID | ProjectStatus | Date |
---|---|---|---|
1 | 1 | Started | 2/10/2020 |
2 | 1 | In Testing | 5/6/2021 |
3 | 1 | Finished | 7/1/2021 |
4 | 2 | In Testing | 1/30/2019 |
5 | 2 | Finished | 3/18/2020 |
6 | 4 | Started | 10/22/2016 |
7 | 4 | Finished | 3/18/2020 |
As you can see from the second table, there is no entry for when Project B 'started' and there is no entries for Project C at all.
I want to add entries for Projects missing a 'started' status with the arbitrary date: 1/1/2000. So the new second table would look like this:
ProjectStatusID | ProjectID | ProjectStatus | Date |
---|---|---|---|
1 | 1 | Started | 2/10/2020 |
2 | 1 | In Testing | 5/6/2021 |
3 | 1 | Finished | 7/1/2021 |
4 | 2 | In Testing | 1/30/2019 |
5 | 2 | Finished | 3/18/2020 |
6 | 4 | Started | 10/22/2016 |
7 | 4 | Finished | 3/18/2020 |
8 | 2 | Started | 1/1/2000 |
9 | 3 | Started | 1/1/2000 |
The first way I thought of was to get all of the Projects that don't have the desired status, but the results of the script I created came out wrong.
SELECT t.ProjectID FROM t1 t
INNER JOIN t2 tt ON t.ProjectID = tt.ProjectID
WHERE pp.ProjectStatus != 'Started'
I then tried going the other direction and found all the Projects that do have the desired status and I succeeded in doing that.
SELECT ProjectStatusID, ProjectID, ProjectStatus FROM t2
WHERE ProjectStatus NOT IN (SELECT ProjectStaus FROM t2
WHERE ProjectStatus != 'Started')
However, I am unsure how to use this result column in another script. I could obviously do a long string using the Where clause and copying a pasting all of the ProjectID values, but that is obviously inefficient, especially if there were many more Projects than the ones I gave in the example above.
I think you just want NOT EXISTS
to check which Projects are missing the 'Started' status.
insert into ProjectStatus (ProjectId, ProjectStatus, [Date])
select ProjectId, 'Started', '1/1/2000'
from Project p
where not exists (
select 1
from ProjectStatus ps
where ps.ProjectId = p.ProjectId
and ps.ProjectStatus = 'Started'
);
And if you wanted to only add the 'Started' status only to projects which had at least one status recorded, but don't have a 'Started' status (which isn't what you asked) then you could just check for the missing ProjectStatus using GROUP BY
and HAVING
e.g.
select ProjectId, 'Started', '1/1/2000'
from ProjectStatus
group by ProjectId
having sum(case when ProjectStatus = 'Started' then 1 else 0 end) = 0;