Запрос справки при использовании таблицы аудита - PullRequest
2 голосов
/ 05 января 2012

Предполагая, что у меня есть две таблицы, одна со следующими столбцами, называемыми lease_period:

tenant_trading_name, suite_id, lease_id, building_id

и другая, называемая lease_period_audit со следующими:

Audit_date, Audit_type, Tenant_trading_name, Suite_id, lease_id, building_id

Каждый раз, когда запись обновляется в lease_period и запись выполняется в lease_period_audit со статусом «Обновлен»».Я пытаюсь найти все обновления, сделанные только в поле tenant_trading_name, но они не увенчались успехом.Пока у меня есть следующее:

select              lpa.*
from                property.lease_period_audit lpa
inner join          property.lease_period lp on lpa.suite_id = lp.suite_id and lpa.lease_id = lp.lease_id and lpa.building_id = lp.building_id
where               audit_type = 'Updated'
                    and lp.tenant_trading_name <> lpa.tenant_trading_name
order by            1 desc  

Где здесь недостаток моего мыслительного процесса?Как это можно сделать / как я должен думать об этом?

Ответы [ 2 ]

2 голосов
/ 10 января 2012

Предполагая, что таблица аудита также регистрирует столбец первичного ключа lease_period, на который здесь ссылаются lp_id для простоты, вы можете попробовать следующий подход:

  1. Найти все строки, где audit_type is 'Updated'.

  2. Ранжировать все строки по audit_date и разделить их по lp_id.

  3. Ранжировать строкиaudit_date разбиение lp_id, suite_id, lease_id, building_id.

  4. Получить разницу между двумя рейтингами.

  5. Позиционировать строки снова на audit_date, разделив их теперь на lp_id, suite_id, lease_id, building_id, (ranking_difference).

  6. Выведите все строки, где последнее значение ранжирования равно 2 или больше.

Первые четырешаги приводят к набору строк, в котором каждая группа последовательных (в порядке возрастания audit_date) строк с одинаковыми значениями suite_id, lease_id, building_id для одного и того же lp_id будет однозначно отличаться значением, рассчитанным как разница между рейтингами # 2& # 3.

Внутри группы каждый ряд, начиная со второго, будет отличаться от pтолько в значении tenant_trading_name, которое как раз то, что нам нужно.Итак, мы снова ранжируем строки, принимая во внимание только что полученный «идентификатор группы», а затем возвращаем каждую строку с рейтингом 2 или выше.

Вот примерная реализация:

WITH marked AS (
  SELECT
    *,
    grp = ROW_NUMBER() OVER (PARTITION BY lp_id
                                 ORDER BY audit_date)
        - ROW_NUMBER() OVER (PARTITION BY lp_id, suite_id, lease_id, building_id
                                 ORDER BY audit_date)
  FROM lease_period_audit
  WHERE audit_type = 'Updated'
),
ranked AS (
  SELECT
    *,
    rnk = ROW_NUMBER() OVER (PARTITION BY lp_id, suite_id, lease_id, building_id, grp
                                 ORDER BY audit_date)
  FROM marked
)
SELECT
  audit_date,
  lp_id,
  tenant_trading_name,
  suite_id,
  lease_id,
  building_id
FROM ranked
WHERE rnk = 2

Примечание.Это предполагает, что таблица аудита регистрирует только реальные изменения, т. Е. Не может быть двух последовательных строк с одинаковым первичным ключом, где все четыре столбца имеют одинаковые значения.

1 голос
/ 07 января 2012

Вы должны подумать что-то вроде этого (псевдокод):

edit : я раньше не осознавал, что в таблице lpa фактически есть все данные, нет необходимости присоединятьсяс LP

select lpa.*
from   lpa 
join   lpa_before on 
           lpa_before.id = lpa.id and 
           lpa_before.date = 
                  (select max(date) from lpa3 where lpa3.date < lpa.date and lpa.id = lpa3.id)
where  auditytype = 'update' and lpa.name <> lpa_before.name

Я надеюсь, что смогу объяснить .. (это не тривиальное решение, но вот что мне приходит в голову)

На английском языке:

ВыберитеLPA регистрирует.Присоединитесь к другому LPA, который будет LPA непосредственно перед оригинальным.Назовите это LPA_BEFORE.Чтобы присоединиться к LPA_BEFORE, вы должны сравнить все идентификаторы из LPA и LPA_BEFORE, и дата LPA_BEFORE должна быть максимальной из LPA, у которых дата меньше, чем у исходного LPA.Сравните названия LPA с LPA_BEFORE

...