Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为什么值发生更改我们可以查询此表以查看什么/什么时候发生了更改。在这种情况下,您可以直接使用distinct对除RunKey和Rundate之外的所有列进行查询,然后将该表与该行数据的min(Rundate)和min(RunKey)进行自联接。这类似于“只_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 为什么值发生更改我们可以查询此表以查看什么/什么时候发生了更改。在这种情况下,您可以直接使用distinct对除RunKey和Rundate之外的所有列进行查询,然后将该表与该行数据的min(Rundate)和min(RunKey)进行自联接。这类似于“只

Sql 为什么值发生更改我们可以查询此表以查看什么/什么时候发生了更改。在这种情况下,您可以直接使用distinct对除RunKey和Rundate之外的所有列进行查询,然后将该表与该行数据的min(Rundate)和min(RunKey)进行自联接。这类似于“只,sql,sql-server,tsql,Sql,Sql Server,Tsql,为什么值发生更改我们可以查询此表以查看什么/什么时候发生了更改。在这种情况下,您可以直接使用distinct对除RunKey和Rundate之外的所有列进行查询,然后将该表与该行数据的min(Rundate)和min(RunKey)进行自联接。这类似于“只插入更改”,这是一个更好的想法。也就是说,不是用未更改的行归档该表,而是在有更改时才插入。这将减小表的大小,并消除您正在创建的额外表。这是否符合业务需求?是否有一种方法也可以捕获旧的价值?这是这里的关键,他想知道更改日期、旧值和新值,以及更改的


为什么值发生更改我们可以查询此表以查看什么/什么时候发生了更改。在这种情况下,您可以直接使用distinct对除RunKey和Rundate之外的所有列进行查询,然后将该表与该行数据的min(Rundate)和min(RunKey)进行自联接。这类似于“只插入更改”,这是一个更好的想法。也就是说,不是用未更改的行归档该表,而是在有更改时才插入。这将减小表的大小,并消除您正在创建的额外表。这是否符合业务需求?是否有一种方法也可以捕获旧的价值?这是这里的关键,他想知道更改日期、旧值和新值,以及更改的列。因此,与插入包含更改的整行不同,他们只想查看更改的特定列、更改日期以及新旧值。更改日期是runDate,假设您每天都运行它。因此,只有更改了才会得到新行,并且日期将是getdate(),它将显示更改的日期。从另一个角度来看,这真的是走了太多的4步。这种方法向您显示更改以及更改的时间,仅在更改时显示。它解决了核心问题,而不必为糟糕的设计使用解决方案IMHO@bm11是的,触发器既可以访问旧值,也可以访问新值。我用实际样本数据对此进行了测试,效果非常好。我正在用大约900k行的完整数据集进行测试。它运行得非常慢,因为我有26列要跟踪更改,而且似乎cte0会为每个运行键的每一列生成一行。@bm11请参阅编辑第二个选项。我将脚本添加到一个光标上,该光标在帐号上迭代并插入到我的表中。适用于所有以前的记录,并将继续创建触发器。您知道如何使用触发器提取列名吗?当我运行nightly insert时,我希望它在帐号级别查看最新的RunKey并进行比较,以查看是否发生了任何更改。 |AccountNo | RunKey | RunDate | Address | Salary | PromotionDate| ---------------------------------------------------------------------------- | 12345 | 2 | 06/20/2017 | 123 Main Street | 60,000 | 01/15/2017 | | 12345 | 3 | 06/21/2017 | 123 Main Street | 60,000 | 01/15/2017 | | 12345 | 4 | 06/22/2017 | 123 Main Street | 65,000 | 06/21/2017 | |AccountNo | RunKey | RunDate | Address | AddressLAG |AddressFlag| Salary | SalaryLAG |SalaryFlag| PromotionDate|PromotionDateLag|PromotionFlag| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | 12345 | 2 | 06/20/2017 | 123 Main Street | 123 Main Street | 0 | 60,000 | 60,000 | 0 | 01/15/2017 | 01/15/2017 | 0 | | 12345 | 3 | 06/21/2017 | 123 Main Street | 123 Main Street | 0 | 60,000 | 60,000 | 0 | 01/15/2017 | 01/15/2017 | 0 | | 12345 | 4 | 06/22/2017 | 123 Main Street | 123 Main Street | 0 | 65,000 | 60,000 | 1 | 01/15/2017 | 06/21/2017 | 1 | | RunKey | AccountNo | ChangedCol | PrevRunDate | RunDate | PrevValue | NewValue | ------------------------------------------------------------------------------------------- | 4 | 12345 | Salary | 06/21/2017 | 06/22/2017 | 60,000 | 65,000 | | 4 | 12345 | PromotionDate | 06/21/2017 | 06/22/2017 | 01/15/2017 | 06/21/2017 |
declare @source table (
                        AccountNo int
                        ,Address varchar(256)
                        ,Salary decimal(16,4)
                        ,PromotionDate datetime)
insert into @source
values
(12345,'123 Main Street',60000,'20170115')


declare @audit table (
                        AccountNo int
                        ,Address varchar(256)
                        ,Salary decimal(16,4)
                        ,PromotionDate datetime
                        ,RunDate datetime)

--load the audit table with the current version of the source table
insert into @audit
select *, getdate() from @source

--show that the tables match currently
select * from @source
select * from @audit

--insert into @audit if there are any changes (notice we haven't made any updates yet)
insert into @audit
select AccountNo, Address, Salary, PromotionDate, getdate() from @source
except 
select AccountNo, Address, Salary, PromotionDate, getdate() from @audit

--show that a record WAS NOT inserted since there was no change. There is only 1 record, the orignal version
select * from @audit

--update the promotion and salary
update @source
set
    PromotionDate = '20170331'
    ,Salary = '65000'

--insert into @audit if there are any changes
insert into @audit
select AccountNo, Address, Salary, PromotionDate, getdate() from @source
except 
select AccountNo, Address, Salary, PromotionDate, getdate() from @audit

--show that a record was inserted since there was a change
select * from @audit
Declare @YourTable Table ([AccountNo] int,[RunKey] int,[RunDate] date,[Address] varchar(50),[Salary] int,[PromotionDate] date)
Insert Into @YourTable Values 
 (12345,2,'06/20/2017','123 Main Street',60000,'01/15/2017')
,(12345,3,'06/21/2017','123 Main Street',60000,'01/15/2017')
,(12345,4,'06/22/2017','123 Main Street',65000,'06/21/2017')


;with cte as (
    Select A.AccountNo
          ,A.RunKey
          ,A.RunDate
          ,B.*
         ,PreValue=Lag(Value)   over (Partition By AccountNo,Item Order by RunDate) 
         ,PreDate =Lag(RunDate) over (Partition By AccountNo,Item Order by RunDate) 
     From  @YourTable A
     Cross Apply ( values ('Address'      ,cast(A.[Address] as varchar(max)))
                         ,('Salary'       ,cast(A.[Salary]  as varchar(max)))
                         ,('PromotionDate',cast(A.[PromotionDate] as varchar(max)))
                 ) B (Item,Value)
)
Select *
 From  cte
 Where Value<>PreValue and PreValue is not null