Бюджет и фактические строки не объединяются при полном внешнем объединении - PullRequest
1 голос
/ 19 марта 2019

Следующий запрос:

select coalesce(to_number(bl.division_code), bud.division) division
,      coalesce(bud.glaccountcode, bl.costcenter_costanalysis_period_periods_year_years_balance_code_attr) glaccountcode
,      coalesce(bud.costcenter, bl.costcenter_code_attr) costcenter
,      coalesce(bud.costunit, bl.code_attr) costunit
,      coalesce(bud.reportingyear, bl.costcenter_costanalysis_period_periods_year_reportingyear_attr) reportingyear
,      coalesce(bud.reportingperiod, bl.costcenter_costanalysis_period_reportingperiod_attr) reportingperiod
,      case when bud.amountdc > 0 then 456 else null end budgetamountdc label 'Budget (anonymized, EUR)'
,      case when bl.balance > 0 then 123 else null end actualsamountdc label 'Actuals (anonymized, EUR)'
,      case
       when bl.division_code is null
       then 'budget'
       when bud.division is null
       then 'balancelines'
       else 'both'
       end
       label 'Source'
from   exactonlinexml..balancelinesperperiodcostanalysis bl
full
outer
join   exactonlinerest..budgets bud
on     bud.division        = to_number(bl.division_code)
and    bud.glaccountcode   = bl.costcenter_costanalysis_period_periods_year_years_balance_code_attr
and    bud.costcenter      = bl.costcenter_code_attr
and    bud.costunit        = bl.code_attr
and    bud.reportingyear   = bl.costcenter_costanalysis_period_periods_year_reportingyear_attr
and    bud.reportingperiod = bl.costcenter_costanalysis_period_reportingperiod_attr

объединяет фактические транзакции на счетах Главной книги со связанными бюджетами на детальном уровне:

  • Точная Онлайн компания (division_code)
  • Финансовый год (reportingyear)
  • Финансовый период (reportingperiod)
  • Счет Главной книги (glaccountcode)
  • Учетный отдел (costcenter)
  • Костюм (costunit)

Я ожидаю максимум одну строку данных на комбинацию этих измерений. Однако для некоторой комбинации возвращаются 2 строки. В одной из этих строк есть метка «бюджет», а в другой - «баланс».

Кажется, что как-то они не слились воедино:

Invantive Query Tool output

Содержимое счета 5050 gl в строках баланса периода 1 в 2019 году представляет собой одну строку с определенной суммой (не равной 0).

Содержимое счета 5050 GL в бюджетах периода 1 в 2019 году также представляет собой одну строку с определенной суммой (не равной 0).

Кажется, я не могу понять, почему строки не объединяются при полном внешнем соединении и объединении.

Что я делаю не так?

1 Ответ

1 голос
/ 19 марта 2019

Вы используете соединение в 6 измерениях.Каждое из этих измерений является частью первичного ключа сальдо, а также бюджетов.Однако некоторые из этих измерений могут содержать нулевые значения.Null - это что-то особенное в логике SQL и определяет неизвестное значение неизвестного типа (могут быть различные типы неизвестных значений).В SQL используется трехзначная логика ( Мистер Брауэр говорит привет ).Посмотрите на результат запроса

select 1=1 are_they_equal_bool1
,      1=0 are_they_equal_bool2
,      null=null are_they_equal_bool3

, он ясно показывает, что null = null оценивается как нечто "серое", что означает null: неизвестно, является ли это истиной или ложью:

null=null has unknown (null) outcome

Вам необходимо компенсировать нулевые значения в вашем объединении.В этом случае вы, вероятно, определите NULL для МВЗ и единицы затрат как финансовую сумму, не связанную с МВЗ и / или единицей затрат.В этом случае нулевые строки баланса и нулевые значения в бюджетах имеют одинаковую семантику.

Чистый путь состоит в том, чтобы адаптировать исходные условия соединения:

and    bud.costcenter      = bl.costcenter_code_attr
and    bud.costunit        = bl.code_attr

, чтобы иметь нулевое значение в обоихстолбцы имеют одинаковое значение:

and    ( ( bud.costcenter is null and bl.costcenter_code_attr is null )
         or 
         bud.costcenter      = bl.costcenter_code_attr 
       )
and    ( ( bud.costunit is null and bl.code_attr is null )
         or 
         bud.costunit      = bl.code_attr 
       )
...