0

谁能建议如何去规范化一个完全规范化的表?尽管谷歌搜索,我还是找不到太多关于它的信息。

每当在 TableA 中更新记录(虽然没有插入,但现在不用担心)时,都会将记录插入到 HistoryOfTableA 中,其中包含已更改字段的值以及执行时的相关时间戳。

例如。

表 A 字段:

TableA_Id, FieldA, FieldB, FieldC, FieldD.... etc

HistoryOfTableA 记录:

HistID, TableA_Id, FieldChanged, OldValue, NewValue, DateCreated
1, 1, 'FieldA', 1, 2, <2013-03-18 12:20:00>
2, 1, 'FieldB', A, B, <2013-03-18 12:20:00>
3, 1, 'FieldC', A, B, <2013-03-18 12:20:00>

情况是我希望创建一些用于报告目的的 SQL。因此,我希望能够指定一个时间点,并能够将这些宿主表条目汇总在一起,并计算出当时 TableA 中该记录的状态。

我在想我可以根据历史表创建表,并在创建日期和表 A 中加入 Id

例如。

select HistA.NewValue, 
       HistB.NewValue, 
       .... 
from FieldA_HistoryOfTableA HistA 
     inner join FieldB_HistoryOfTableA HistB on HistA.DateCreated = HistB.DateCreated
       and HistA.TableA_Id = HistB.TableA_Id 
     inner join ... etc
where HistA.FieldChanged = 'FieldA'
and HistB.FieldChanged = 'FieldB'
and .... etc...

但我不认为这会给我我想要的一切,而且我可能无法纯粹在 SQL 中做到这一点。顺便说一句,TableA 中有 20 个字段,因此尝试加入 20 个表可能并不明智。

4

3 回答 3

2

你的问题不是表格被标准化,而是它不是。

一个表中的字段标识的数据是由另一个表中的数据标识的,这样查询起来非常复杂。

完全规范化的版本还将字段存储TableA在单独的表中:

TableA
------------
TableA_Id

TableAFields
-------------
TableA_Id
FieldId
Value

Field
---------
FieldId
FieldName

HistoryOfTableA
----------------
TableA_Id
FieldId
OldValue
ChangedDate

现在您可以加入历史表中的字段。这会有点棘手,但至少它不会是一个有 20 个连接的查询。

于 2013-03-19T12:46:16.897 回答
1

If you want the most recent records from the history table, you can use the following SQL:

select ht.*
from (select ht.*,
             ROW_NUMBER() over (partition by FieldChanged, TableA_Id order by DateCreated desc) as seqnum
      from HistoryOfTableA ht
      where datecreated <= YOURDATEHERE
     ) ht
where seqnum = 1

If you want this as a single record, you should either pivot or do an aggregation. Here is the latter approach:

select ht.TableA_id,
       max(case when FieldName = 'FieldA' then NewValue end) as FieldA,
       . . .
from (select ht.*,
             ROW_NUMBER() over (partition by FieldChanged, TableA_Id order by DateCreated desc) as seqnum
      from HistoryOfTableA ht
      where datecreated <= YOURDATEHERE
     ) ht
where seqnum = 1
group by TableA_id
于 2013-03-19T13:56:46.480 回答
-1

您可以尝试使用 TableA 中的 XML 列来记录 TableA 中每一行的历史记录。即每一行都有一个XML 类型的列并记录该行的历史。然后您可以将行拉入您的应用程序(如果行数很大,则以批处理方式),并找出 TableA 中每条记录的历史记录

于 2013-03-19T12:38:17.437 回答