Сравнение двух таблиц по каждому полю

IFK
Дата: 16.11.2009 15:07:48
Уважаемые форумчане!

Простенькая проблемка: есть две таблицы, Таб1 и Таб2. Структура абсолютно одинаковая. Первая таблица содержит рабочий набор записей (Таб1). Вторая таблица содержит копию набора записей из первой таблицы, сделанную, скажем неделю назад (Таб2). В обоих таблицах есть уникальное поле, по которому можно сравнить записи. За это время набор записей в первой таблице (Таб1) изменился: добавились новые, значения в полях изменились и т.д. Задача: необходимо провести сравнение двух таблиц и указать в каких полях и записях есть изменения по сравнению с архивной таблицей (Таб2) - скажем, изменить значения поля "Статус". Как бы это провернуть без пошагового сравнения каждого поля для каждой записи?

Кроме "SELECT поля FROM Таб1 INNER JOIN Таб2 ON Таб1.FMID = Таб2.FMID" пока ничего не придумал. :(
ё
Дата: 16.11.2009 15:32:20
как-то так можна
SELECT 
IIf(IsNull(Таб2.FMID), 'Новая запись - ' & Таб1.FMID, 'Изменения в ' & Таб1.FMID) As FMID,
IIf(Nz(Таб1.поле1)<>Nz(Таб2.поле1), Nz(Таб1.поле1, 'NULL'), Null) As [Изменения в Поле1], 
IIf(Nz(Таб1.поле2)<>Nz(Таб2.поле2), Nz(Таб1.поле2, 'NULL'), Null) As [Изменения в Поле2], 
... 
FROM Таб1 
LEFT JOIN Таб2 
  ON Таб1.FMID = Таб2.FMID
IFK
Дата: 16.11.2009 15:38:34
Спасибо! Я, в принципе, так и думал. :)
ILL HEAD
Дата: 16.11.2009 15:45:52
IFK
Кроме "SELECT поля FROM Таб1 INNER JOIN Таб2 ON Таб1.FMID = Таб2.FMID" пока ничего не придумал. :(

-- это на изменение в полях
SELECT 'поле1 изменилось' FROM Таб1 INNER JOIN Таб2 ON Таб1.FMID = Таб2.FMID AND Таб1.поле1 <> Таб2.поле1
UNION
...
SELECT 'полеN изменилось' FROM Таб1 INNER JOIN Таб2 ON Таб1.FMID = Таб2.FMID AND Таб1.полеN <> Таб2.полеN
-- это на добавление
UNION
SELECT 'добавлена запись Таб1.FMID='+Таб1.FMID FROM Таб1 LEFT JOIN Таб2 ON Таб1.FMID = Таб2.FMID WHERE Таб2.FMID IS NULL
-- это на удаление
UNION
SELECT 'удалена запись Таб2.FMID='+Таб2.FMID FROM Таб1 RIGHT JOIN Таб2 ON Таб1.FMID = Таб2.FMID WHERE Таб1.FMID IS NULL
а так ?
ILL HEAD
Дата: 16.11.2009 15:47:59
косячок. так вернее
-- это на изменение в полях
SELECT 'поле1 изменилось в FMID='+Таб1.FMID FROM Таб1 INNER JOIN Таб2 ON Таб1.FMID = Таб2.FMID AND Таб1.поле1 <> Таб2.поле1
UNION
...
SELECT 'полеN изменилось в FMID='+Таб1.FMID FROM Таб1 INNER JOIN Таб2 ON Таб1.FMID = Таб2.FMID AND Таб1.полеN <> Таб2.полеN
-- это на добавление
UNION
SELECT 'добавлена запись Таб1.FMID='+Таб1.FMID FROM Таб1 LEFT JOIN Таб2 ON Таб1.FMID = Таб2.FMID WHERE Таб2.FMID IS NULL
-- это на удаление
UNION
SELECT 'удалена запись Таб2.FMID='+Таб2.FMID FROM Таб1 RIGHT JOIN Таб2 ON Таб1.FMID = Таб2.FMID WHERE Таб1.FMID IS NULL
mds_world
Дата: 16.11.2009 16:44:55
Можно сделать процедуру, которая в цикле будет сравнивать изменившиеся значения полей. Типа такой
Sub sravnTabl(t1, t2, nameKeyField)
    Dim s, fld As Field, tdf As TableDef, db As Database
    Set db = CurrentDb
    Set tdf = db.TableDefs(t1)
    For Each fld In tdf.Fields
        If fld.Name <> nameKeyField Then
            s = s & vbCrLf & " select '" & fld.Name & "' as [Поле], " & t1 & "." _
            & nameKeyField & ", cstr(" & t1 & ".[" & fld.Name & "]) as [ИсхТабл], cstr(" & t2 & ".[" & fld.Name _
            & "]) as [ТекТабл] from " & t1 & " Inner join " & t2 & " on " _
            & t1 & "." & nameKeyField & "=" & t2 & "." & nameKeyField _
            & " where " & t1 & ".[" & fld.Name & "]<>" & t2 & ".[" & fld.Name & "]" _
            & vbCrLf & " Union all"
            
        End If
    Next
    s = Left(s, Len(s) - 9)
    Debug.Print s
    db.QueryDefs("qTemp").sql = s
    DoCmd.OpenQuery ("qTemp")
End Sub

В параметрах процедуры t1 - имя архивная таблица, t2 - имя текущей. nameKeyField это имя ключевого поля.

Запрос "qTemp" это просто запрос, в который запихивается сгенерированный SQL-код
IFK
Дата: 16.11.2009 17:19:37
Огромный сенкс всем участникам! Буду пробовать. :)
Папа Игорь
Дата: 16.11.2009 17:38:40
IFK
...Задача: необходимо провести сравнение двух таблиц и указать в каких полях и записях есть изменения по сравнению с архивной таблицей (Таб2)...


Скажите пожалуйста, а нельзя ли Вашу задачу перефразировать так:

Необходимо отследить все изменения в Таб1 с момента создания последней Таб2.

После этого Вы, возможно, будете решать эту задачу другими методами.
IFK
Дата: 17.11.2009 15:17:33
Папа: можно. Спасибо за переформулировку! :)
Задачу решил: SELECT поля, IIf(сравнение полей) as SysInfo FROM Tab1 INNER JOIN Tab2 ON Tab1.FMID=Tab2.FMID
гм,
Дата: 17.11.2009 15:38:59
Папа Игорь

Скажите пожалуйста, а нельзя ли Вашу задачу перефразировать так:
Необходимо отследить все изменения в Таб1 с момента создания последней Таб2.


IFK

Папа: можно.


судя по решению - нельзя
если какая-то запись изменилась, а потом вернулась в исх. - ничё не будет видно