Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вывод дельты данных  [new]
Wrun
Member [заблокирован]

Откуда:
Сообщений: 126
Добрый день!

Разъясните такую ситуацию:
Задача - вычисление дельты (т.е. разницы) данных двух таблиц. Т.е. Новое и Предыдущее состояние.

На данный момент выглядит так - Вывожу дельту:

Есть таблицы tmpTable1, preTable1 и Table1

В процедуре наполняю tmpTable1 новыми данными.
Затем сверяю tmpTable1 и preTable1 для выявления дельты, и записываю результат в Table1.

Неудобство в том что нужно вести 3 структуры таблиц параллельно.
Попробовал уйти от этого и сделал одну таблицу Table1 с полем TYP (PRE,TMP,Delta)

Но резко увеличилось время вычисления дельты.
Я так понимаю это из-за того что чтение и запись происходит в одной таблице.
Есть ли какие-нибудь альтернативные компромиссные решения?

Индексы на поле TYP конечно помогли, но всё равно время дольше!

Пример вычисления дельты:

INSERT INTO Table1 (ID,[somecols...],systyp,syshash)
SELECT ID
	,[somecols...]
	,'add' as 'systyp'
	,syshash
	FROM Table1 
	WHERE systyp = 'TMP' and ID not in (select ID from Table1 where systyp = 'PRE')
UNION
SELECT tmp.ID
	,tmp.[somecols...]
	,'cng' as 'systyp'
	,tmp.syshash
	FROM Table1 tmp
	JOIN Table1 pre ON pre.systyp='PRE' and tmp.id = pre.id and tmp.syshash != pre.syshash
	WHERE tmp.systyp='TMP'
UNION
SELECT ID
	,[somecols...]
	,'del' as 'systyp'
	,syshash
	FROM Table1
	WHERE systyp='PRE' and ID not in (select id from Table1 where systyp='TMP')
;




P.S. syshash это поле вычисляемое заранее где делается MD5 от всех нужных полей для сверки изменений
3 авг 12, 11:23    [12957070]     Ответить | Цитировать Сообщить модератору
 Re: Вывод дельты данных  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Wrun,

Может быть вам поможет MERGE
3 авг 12, 11:38    [12957173]     Ответить | Цитировать Сообщить модератору
 Re: Вывод дельты данных  [new]
Serg_77m
Member

Откуда: Донецк
Сообщений: 237
Может быть, так пройдёт?

select sum(FLAG) as Delta,field1,field2,...,fieldN
from (
  select -1 as FLAG,field1,field2,...fieldN
  from TableOld
  union all
  select 1 as FLAG,field1,field2,...,fieldN
  from TableNew
) a
group by field1,field2,...fieldN
having sum(FLAG)<>0       -- оставить по вкусу
6 авг 12, 21:09    [12971235]     Ответить | Цитировать Сообщить модератору
 Re: Вывод дельты данных  [new]
Wrun
Member [заблокирован]

Откуда:
Сообщений: 126
Интересное решение, но если я правильно понял то остается тот же union и считывание из 2х таблиц... но попробую погонять
7 авг 12, 19:07    [12977299]     Ответить | Цитировать Сообщить модератору
 Re: Вывод дельты данных  [new]
Serg_77m
Member

Откуда: Донецк
Сообщений: 237
Wrun,

если в одной таблице хранить и предыдущее, и последнее состояние, то UNION не нужен, и получится одно считывание.
Если я правильно понял Ваш пример, то дельта должна получиться так:

select 
  ID,[somecols...],
  case sum(FLAG) over (partition by ID)
    when 0 then 'cng'
    when 1 then 'add'
    when -1 then 'del'
  end as systyp
from (
  select
    sum(case systyp when 'TMP' then 1 when 'PRE' then -1 end) as FLAG,
    ID,[somecols...]
  from Table1 
  where systyp in ('TMP','PRE')
  group by ID,[somecols...]
) a
where FLAG<>0
7 авг 12, 20:09    [12977571]     Ответить | Цитировать Сообщить модератору
 Re: Вывод дельты данных  [new]
Wrun
Member [заблокирован]

Откуда:
Сообщений: 126
Очень интересное решение, щас погружусь и попробую понять!
7 авг 12, 20:34    [12977659]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить