Невозможно получить нулевые значения при полном внешнем соединении - PullRequest
0 голосов
/ 07 мая 2020

Я использую SQL Сервер. У меня есть таблица Dim_date со всеми датами мая 2020 года

Datekey
---------
20200501 
20200502
20200503
20200504
20200505
20200506
20200507
....

И у меня есть таблица Fact_Controls , в которой количество элементов управления указано c center делали каждый день.

Date_Ctl | Id_Centre | No_Controls
---------------------------
20200505| 01415     |1
20200505| 01415     |1
20200505| 01415     |1
20200506| 01415     |1
20200506| 01415     |1

Мне нужен запрос, который показывает мне количество элементов управления, выполненных центром, даже если оно равно 0 или ноль, например:

Datekey | Id_Centre | No_Controls
---------------------------
20200501| 01415     |0
20200502| 01415     |0
20200503| 01415     |0
20200504| 01415     |0
20200505| 01415     |3
20200506| 01415     |2
20200507| 01415     |0
....

Я делаю это, но не получаю того, чего ожидал:

select 
     dd.DateKey,
     sum(No_Controls) as total_controls
from 
      [Fact_Controls] fc
full outer join 
     [dm].[Dim_Date] dd on  fc.Date_Ctl = dd.DateKey
where 
     fc.[Id_Centre]='01415' 
    and fc.Date_Ctl between 20200501 and 20200520
    and dd.DateKey is null
group by dd.DateKey

Ответы [ 2 ]

0 голосов
/ 07 мая 2020

Внешняя объединенная строка имеет пустые значения в столбцах, в которых нет соответствующей строки. Таким образом, это

where fc.[Id_Centre]='01415' and fc.Date_Ctl between 20200501 and 20200520

удалит все внешние соединенные f c строки.

Это

where dd.DateKey is null

, с другой стороны, удалит все не внешние соединенные dd rows.

Более того, почему полное внешнее соединение? Разве таблица дат не должна содержать все даты? Кажется, вам нужно простое левое внешнее соединение:

select
  dd.datekey,
  sum(fc.no_controls) as total_controls
from dm.dim_date dd 
left join fact_controls fc on  fc.date_ctl = dd.datekey and fc.id_centre = '01415' 
where dd.datekey between '20200501' and '20200520'
group by dd.datekey
order by dd.datekey;

Или (агрегация перед соединением):

select dd.datekey, fc.total_controls
from dm.dim_date dd 
left join
(
  select date_ctl, sum(no_controls) as total_controls
  from fact_controls
  where id_centre = '01415'
  group by date_ctl
) fc on  fc.date_ctl = dd.datekey
where dd.datekey between '20200501' and '20200520'
order by dd.datekey;

Или (агрегация непосредственно по строке даты):

select dd.datekey, fc.total_controls
from dm.dim_date dd 
outer apply
(
  select sum(no_controls) as total_controls
  from fact_controls
  where id_centre = '01415'
  and by date_ctl = dd.datekey
) fc
where dd.datekey between '20200501' and '20200520'
order by dd.datekey;

Вы можете использовать coalesce, чтобы преобразовать нули в нули в ваших результатах.

Если datekey + id_centre уникальны в вашей таблице fact_controls вам не нужно агрегирование (SUM) в все конечно.

0 голосов
/ 07 мая 2020

Используйте ВНЕШНЕЕ ПРИМЕНЕНИЕ

SELECT * FROM [Dim_Date] D 
OUTER APPLY 
   ( 
   SELECT * FROM [Fact_Controls] F 
   WHERE F.Date_Ctl = D.DateKey 
   ) A 
GO
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...