SQL Server - нужен запрос SQL для выявления / выделения определенных изменений в таблице аудита - PullRequest
2 голосов
/ 23 июня 2010

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

InvoiceID CustomerID  ItemSold    AmountSold     SalesPerson  ModifyDate
1001      96          Widget      800            Robert       2001-1-1
1006      85          Thinger     350            Phil         2001-1-8
1001      96          Widget      800            Bobby        2001-1-9
1005      22          Widget      400            Robert       2001-1-10
1006      44          Thinger     500            Mike         2001-2-5
1001      96          Widget      250            Robert       2001-6-4

И я хочу написать запрос, который будет идентифицировать всякий раз, когда поле SalesPerson меняет , для любого конкретного InvoiceID (например, всякий раз, когда продавец меняет продажу на свое имя).

Итак, в приведенном выше примере я хотел бы определить изменение, которое произошло в 2001-1-9 годах, когда продажа InvoiceID 1001 перешла от Роберта к Бобби, и изменение в 2001-6-4, где оно произошло. вернулся к Роберту из Бобби ... так что два изменения для этого конкретного удостоверения личности. И я также хотел бы отметить изменение в 2001-2-5, когда продажа InvoiceID 1006 перешла от Фила к Майку.

Как мне написать SQL-запрос, который определит / выделит эти изменения?

В настоящее время таблица не содержит первичного ключа, но я могу добавить его при необходимости.

Ответы [ 4 ]

3 голосов
/ 23 июня 2010

Если вы добавите первичный ключ (что вы должны сделать, это в конечном итоге упростит некоторые запросы, которые вам нужны для этой таблицы), тогда вам понадобится самостоятельное соединение.Нечто подобное может сделать это:

select a.invoiceId, a.SalesPerson as FirstSalesPerson, 
    a.Modifydate as FirstModifyDate, b.SalesPerson as SecondSalesPerson, 
    B.Modifydate as SecondModifyDate  
from myaudittable a
join myadudittable b
   on a.InvoiceID = b.InvoiceID
where a.AuditIDd <>b.AuditID and a.ModifyDate < b.ModifyDate
   and a.SalesPerson<>b.SalesPerson
order by InvoiceID
2 голосов
/ 23 июня 2010

Это должно сделать это.

declare @Audit table (
    InvoiceID int,
    CustomerID int,
    ItemSold varchar(10),
    AmountSold int,
    SalesPerson varchar(10),
    ModifyDate datetime
)

insert into @Audit
    (InvoiceID, CustomerID, ItemSold, AmountSold, SalesPerson, ModifyDate)
    values
    (1001, 96, 'Widget', 800, 'Robert', '2001-1-1'),
    (1006, 85, 'Thinger', 350, 'Phil', '2001-1-8'),
    (1001, 96, 'Widget', 800, 'Bobby', '2001-1-9'),
    (1005, 22, 'Widget', 400, 'Robert', '2001-1-10'),
    (1006, 44, 'Thinger', 500, 'Mike', '2001-2-5'),
    (1001, 96, 'Widget', 250, 'Robert', '2001-6-4')

select a2.InvoiceID, a2.SalesPerson, a2.ModifyDate
    from @Audit a1
        inner join @Audit a2
            on a1.InvoiceID = a2.InvoiceID
                and a1.ModifyDate < a2.ModifyDate
                and a1.SalesPerson <> a2.SalesPerson
1 голос
/ 25 июня 2010

Вот более полный ответ, я думаю.Предполагается:

  1. как минимум SQL Server 2005
  2. , что в столбце ModifyDate указано время создания записи в журнале аудита.
  3. существованиепервичный ключ идентификации, AuditID

declare @Audit table 
(
    AuditID int identity(1,1),
    InvoiceID int,
    CustomerID int,
    ItemSold varchar(10),
    AmountSold int,
    SalesPerson varchar(10),
    ModifyDate datetime
)

;with orders (InvoiceID, SalesPerson, ModifyDate, idx)
as
(
    select 
        InvoiceID, 
        SalesPerson, 
        ModifyDate, 
        row_number() over (partition by InvoiceID order by AuditID desc)
    from @Audit
) 

select o2.InvoiceID, o2.SalesPerson, o2.ModifyDate from orders o1 inner join orders o2 
on 
    o1.InvoiceID = o2.InvoiceID and 
    o1.SalesPerson <> o2.SalesPerson and
    o1.idx = o2.idx-1
order by InvoiceID, ModifyDate desc
0 голосов
/ 29 июня 2010

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

 select InvoiceId,SalesPerson,auditdate from myaudittable where InvoiceId in 
 (select distinct a.InvoiceId 
 from myaudittable a inner join myaudittable b on a.InvoiceId = b.InvoiceId and         
 a.SalesPerson <> b.SalesPerson)                
 group by InvoiceId,SalesPerson
...