A family of Microsoft relational database management systems designed for ease of use.
Why not have a table for all positions rather than just the vacant ones. You could include a Boolean (Yes/No) column, Current, for instance to indicate current positions and set its value to false if a position is abolished. That way you can keep track of past and present positions. In the Employees table you'd them have a foreign key column, PositionID say, referencing the primary key of the Positions table.
The total number of current positions can be returned with:
SELECT COUNT(*)
FROM Positions
WHERE Current;
Occupied positions with:
SELECT COUNT(*)
FROM Positions INNER JOIN Employees
ON Positions.PositionID = Employees.PositionID
WHERE Current AND Status <> "Terminated";
Vacant positions with:
SELECT COUNT(*)
FROM Positions
WHERE Current
AND NOT EXISTS
(SELECT *
FROM Employees
WHERE Status <> "Terminated"
AND Employees.PositionID = Positions.PositionID);
Ideally you should have a means of preventing more than one row being inserted into the Employees table with the same PositionID where the employee's Status is not 'Terminated'. This can't be done with an index as it would be legitimate to have multiple rows with same PositionID and a Status value of 'Terminated'. It can be done by applying a CONSTRAINT to the Employees table, however. This is done by executing a DDL statement, DDL (data definition language) being that part of SQL used for creating or amending table definitions. In Access, however, this can't be executed directly from the query designer as you would a normal SQL 'action' query, but must be done with code, which can simply be entered in the debug window (aka 'immediate' window). In this case it would be:
CurrentProject.Connection.Execute "ALTER TABLE Employees ADD CONSTRAINT EmployeePosition CHECK((SELECT COUNT(*) FROM Employees WHERE Status <> "Terminated" GROUP BY EmployeeID, PositionID HAVING COUNT(*) > 1) IS NULL)"
Enter this as a single line. It should prevent the same position being occupied by two employees simultaneously (unless you have job sharing of course). I think I've got the logic right, but if it doesn't work you can remove the constraint with:
CurrentProject.Connection.Execute "ALTER TABLE Employees DROP CONSTRAINT EmployeePosition"