Во-первых, я бы порекомендовал вам прекратить хранить даты в виде текста и использовать правильные типы данных.
Чтобы сделать то, что вам нужно, составьте список всех дат и местоположений, выбрав каждый из столбцов дат и местоположенияи объединить их в один результат (первый cte - allDates).Затем нам нужен отдельный список (второй cte - агрегированный) для выбора и подсчета количества строк в вашей таблице, которые соответствуют текущим значениям даты / местоположения.
Вот полное решение:
declare @JOBS table(JOB_ID int, DateOpen varchar(10), DateFinish varchar(10), DateClose varchar(10), Location varchar(5))
insert into @JOBS values
( 100, '16-Dec-18', '18-Dec-18', '19-Dec-18', 'A'),
( 101, '16-Dec-18', '18-Dec-18', '19-Dec-18', 'A'),
( 102, '17-Dec-18', '19-Dec-18', '20-Dec-18', 'C'),
( 103, '10-Dec-18', '11-Dec-18', '16-Dec-18', 'D'),
( 104, '17-Dec-18', '19-Dec-18', '18-Dec-18', 'E')
;with allDates as (
select convert(date, DateOpen) as [Date], Location from @JOBS
union
select convert(date, DateFinish), Location from @JOBS
union
select convert(date, DateClose), Location from @JOBS
),
aggregated as (
select [Date], Location
from allDates
group by [Date], Location
)
select
a.Date
, (select count(*) from @JOBS where a.[Date] = DateOpen and a.Location = Location) [Open]
, (select count(*) from @JOBS where a.[Date] = DateFinish and a.Location = Location) Finished
, (select count(*) from @JOBS where a.[Date] = DateClose and a.Location = Location) Closed
, Location
from aggregated a
where a.Date between '20181216' and '20181217'