Advertisement
Guest User

Bi-temporal Anchor Modeling by Bas van den Berg

a guest
Nov 3rd, 2011
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
T-SQL 14.05 KB | None | 0 0
  1. /*
  2.  Simple Bitemporal Test (using Anchor Modeling)
  3.  http://www.temporaldata.com/wp-content/uploads/2011/04/bitemporal-support-for-a-temporal-example.swf
  4. */
  5.  
  6. -- Anchor table
  7. CREATE TABLE [dbo].[FI_FinancialInstrument] (
  8.     [FI_ID] [int] IDENTITY(1,1) NOT NULL,
  9.     [Metadata_FI] [int] NOT NULL,
  10.     PRIMARY KEY CLUSTERED (
  11.         [FI_ID] ASC
  12.     )
  13. );
  14.  
  15. GO
  16.  
  17. -- Attribute table
  18. --drop table [dbo].[FI_RAT_FinancialInstrument_Rating]
  19. CREATE TABLE [dbo].[FI_RAT_FinancialInstrument_Rating] (
  20.     [FI_ID] [int] NOT NULL,
  21.     [FI_RAT_FinancialInstrument_Rating] [char](1) NOT NULL,
  22.     -- Changing time (Anchor Modeling),  Valid time (Snodgrass), Effective time (Johnston)
  23.     [FI_RAT_ChangedAt] [date] NOT NULL,
  24.     [FI_RAT_IsValid] [bit] NOT NULL,
  25.     [Metadata_FI_RAT] [int] NOT NULL,
  26.     PRIMARY KEY CLUSTERED (
  27.         [FI_ID] ASC,
  28.         [FI_RAT_ChangedAt] DESC
  29.     ),
  30. --  FOREIGN KEY ([FI_ID]) REFERENCES [dbo].[FI_FinancialInstrument] ([FI_ID])
  31. );
  32.  
  33.  
  34. -- Attribute table
  35. -- drop table [dbo].[HISTORY_FI_RAT_FinancialInstrument_Rating]
  36. CREATE TABLE [dbo].[HISTORY_FI_RAT_FinancialInstrument_Rating](
  37.     [FI_ID] [int] NOT NULL,
  38.     [FI_RAT_FinancialInstrument_Rating] [char](1) NOT NULL,
  39.     -- Changing time (Anchor Modeling),  Valid time (Snodgrass), Effective time (Johnston)
  40.     [FI_RAT_ChangedAt] [date] NOT NULL,
  41. -- Recording time (Anchor Modeling), Transaction time (Snodgrass), Assertion time (Johnston)
  42.     [FI_RAT_RecordedAt] [date] NOT NULL,
  43.     [FI_RAT_IsValid] [bit] NOT NULL,
  44.     [Metadata_FI_RAT] [int] NOT NULL,
  45.     PRIMARY KEY CLUSTERED (
  46.         [FI_ID] ASC,
  47.         [FI_RAT_ChangedAt] DESC,
  48.         [FI_RAT_RecordedAt] DESC
  49.     ),
  50. --  FOREIGN KEY ([FI_ID]) REFERENCES [dbo].[FI_FinancialInstrument] ([FI_ID])
  51. );
  52.  
  53.  
  54. GO
  55.  
  56. -- Meta date Anchor table
  57. CREATE TABLE [dbo].[MD_MetaData] (
  58.     [MD_ID] [int] NOT NULL,
  59.     [MD_RecordedAt] datetime NOT NULL
  60.     PRIMARY KEY CLUSTERED (
  61.         [MD_ID] ASC
  62.     )
  63. );
  64.  
  65. GO
  66.  
  67. /*
  68.     There are nine 'perspectives' of the information resulting
  69.     from latest, point-in-time, and interval perspectives
  70.     taken over the two timelines (changing and recording).
  71.     I will show three of them here.
  72. */
  73.  
  74. -- latest for changing time and latest for recording time
  75. IF  EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[llFI_FinancialInstrument]'))
  76. DROP VIEW [dbo].[llFI_FinancialInstrument]
  77. GO
  78.  
  79. CREATE VIEW [dbo].[llFI_FinancialInstrument]
  80. AS
  81. SELECT
  82.    [FI].FI_ID,
  83.    [FI].Metadata_FI,
  84.    [FI_RAT].FI_RAT_FinancialInstrument_Rating,
  85.    [FI_RAT].FI_RAT_ChangedAt,
  86.    [MD].MD_RecordedAt FI_RAT_RecordedAt,
  87.    [FI_RAT].Metadata_FI_RAT
  88. FROM
  89.    [dbo].[FI_FinancialInstrument] [FI]
  90. LEFT JOIN
  91.    [dbo].[FI_RAT_FinancialInstrument_Rating] [FI_RAT]
  92. ON
  93.    [FI_RAT].FI_ID = [FI].FI_ID
  94. AND
  95.    [FI_RAT].FI_RAT_ChangedAt = (
  96.       SELECT
  97.          max(sub.FI_RAT_ChangedAt)
  98.       FROM
  99.          [dbo].[FI_RAT_FinancialInstrument_Rating] sub
  100.       WHERE
  101.          sub.FI_ID = [FI].FI_ID
  102. /*
  103.       AND -- latest reliability equals 1 can be removed because unreliable data is moved to HISTORY table
  104.         (
  105.             select top 1
  106.                 rel.FI_RAT_Reliability
  107.             from
  108.                 [dbo].[FI_RAT_FinancialInstrument_Rating] rel
  109.             where
  110.                 rel.FI_ID = [FI].FI_ID
  111.             and
  112.                 rel.FI_RAT_ChangedAt = sub.FI_RAT_ChangedAt
  113.             order by
  114.                 rel.FI_RAT_RecordedAt desc
  115.          ) > 0 */
  116.     )
  117. /*
  118. AND
  119.    [FI_RAT].FI_RAT_RecordedAt = (
  120.         SELECT
  121.             MAX(sub.FI_RAT_RecordedAt)
  122.         FROM
  123.             [dbo].[FI_RAT_FinancialInstrument_Rating] sub
  124.         WHERE
  125.             sub.FI_ID = [FI_RAT].FI_ID
  126.         AND
  127.             sub.FI_RAT_ChangedAt = [FI_RAT].FI_RAT_ChangedAt
  128.     );
  129. */
  130. LEFT JOIN
  131.     dbo.MD_MetaData MD on MD.MD_ID = FI_RAT.Metadata_FI_RAT
  132.  
  133. GO
  134.  
  135. -- point-in-time for changing time and latest for recording time
  136. CREATE FUNCTION [dbo].[plFI_FinancialInstrument] (
  137.     @timepoint datetime
  138. )
  139. RETURNS TABLE
  140. RETURN
  141. SELECT
  142.    [FI].FI_ID,
  143.    [FI].Metadata_FI,
  144.    [FI_RAT].FI_RAT_FinancialInstrument_Rating,
  145.    [FI_RAT].FI_RAT_ChangedAt,
  146.    [MD].MD_RecordedAt FI_RAT_RecordedAt,
  147.    [FI_RAT].Metadata_FI_RAT
  148. FROM
  149.    [dbo].[FI_FinancialInstrument] [FI]
  150. LEFT JOIN
  151.    [dbo].[FI_RAT_FinancialInstrument_Rating] [FI_RAT]
  152. ON
  153.    [FI_RAT].FI_ID = [FI].FI_ID
  154. AND
  155.    [FI_RAT].FI_RAT_ChangedAt = (
  156.       SELECT
  157.          max(sub.FI_RAT_ChangedAt)
  158.       FROM
  159.          [dbo].[FI_RAT_FinancialInstrument_Rating] sub
  160.       WHERE
  161.          sub.FI_ID = [FI].FI_ID
  162.       AND
  163.          sub.FI_RAT_ChangedAt <= @timepoint
  164.     )
  165.     LEFT JOIN
  166.     dbo.MD_MetaData MD on MD.MD_ID = FI_RAT.Metadata_FI_RAT
  167.  
  168. GO
  169.  
  170. /****** Object:  View [dbo].[h_FI_RAT_FinancialInstrument_Rating]    Script Date: 10/25/2011 19:28:22 ******/
  171. IF  EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[h_FI_RAT_FinancialInstrument_Rating]'))
  172. DROP VIEW [dbo].[h_FI_RAT_FinancialInstrument_Rating]
  173. GO
  174.  
  175. CREATE VIEW [dbo].[h_FI_RAT_FinancialInstrument_Rating] as
  176. select [FI_ID]
  177.       ,[FI_RAT_FinancialInstrument_Rating]
  178.       ,[FI_RAT_ChangedAt]
  179.       ,[FI_RAT_RecordedAt]
  180.       ,[FI_RAT_IsValid]
  181.       , 1 FI_RAT_Retracted
  182.       ,[Metadata_FI_RAT]
  183.       ,MD.MD_RecordedAt retractedAt
  184.       FROM [AM_Fin_instrument2].[dbo].[HISTORY_FI_RAT_FinancialInstrument_Rating]
  185.       inner join MD_MetaData MD on [Metadata_FI_RAT] = MD.MD_ID
  186.       UNION ALL
  187.       SELECT [FI_ID]
  188.       ,[FI_RAT_FinancialInstrument_Rating]
  189.       ,[FI_RAT_ChangedAt]
  190.       ,[MD].MD_RecordedAt FI_RAT_RecordedAt
  191.       ,[FI_RAT_IsValid]
  192.       , 0 FI_RAT_Retracted
  193.       ,[Metadata_FI_RAT]
  194.       , null retractedAt
  195.         FROM   [dbo].[FI_RAT_FinancialInstrument_Rating] FI_RAT2
  196.         LEFT JOIN dbo.MD_MetaData MD on MD.MD_ID = FI_RAT2.Metadata_FI_RAT
  197.  
  198. GO
  199.  
  200. IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ppFI_FinancialInstrument]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
  201. DROP FUNCTION [dbo].[ppFI_FinancialInstrument]
  202. GO
  203.  
  204. -- point-in-time for changing time and point-in-time for recording time
  205. CREATE FUNCTION [dbo].[ppFI_FinancialInstrument] (
  206.     @changingTimepoint datetime,
  207.     @recordingTimepoint datetime   
  208. )
  209. RETURNS TABLE
  210. RETURN
  211.  
  212. select * from (
  213. SELECT
  214.    [FI].FI_ID,
  215.    [FI].Metadata_FI,
  216.    [FI_RAT].FI_RAT_FinancialInstrument_Rating,
  217.    [FI_RAT].FI_RAT_ChangedAt,
  218.    [FI_RAT].FI_RAT_RecordedAt,
  219.    [FI_RAT].Metadata_FI_RAT
  220.    , row_number() over (partition by FI_RAT.FI_ID order by  FI_RAT_ChangedAt Desc) seq_ChangedAt
  221.    , row_number() over (partition by FI_RAT.FI_ID, FI_RAT_ChangedAt order by  FI_RAT_RecordedAt Desc) seq_RecordedAt
  222. FROM
  223.    [dbo].[FI_FinancialInstrument] [FI]
  224. LEFT JOIN
  225.    [dbo].[h_FI_RAT_FinancialInstrument_Rating] [FI_RAT] -- use history view, because we also consider retracted values
  226. ON
  227.    [FI_RAT].FI_ID = [FI].FI_ID
  228. WHERE
  229.       FI_RAT_RecordedAt <= @recordingTimepoint
  230.   AND (retractedAt is NULL OR retractedAt > @recordingTimepoint)
  231.   AND FI_RAT_ChangedAt <= @changingTimepoint
  232. ) q
  233. where seq_ChangedAt=1 and seq_RecordedAt=1
  234.  
  235.  
  236. GO
  237. */
  238. -- =============================================
  239. -- Author:      Bas van den Berg
  240. -- Create date: 2011-11-03
  241. -- Description: This will retract a record. i.e. move it to the HISTORY table and then delete the source
  242. -- =============================================
  243. CREATE PROCEDURE retract
  244.     -- Add the parameters for the stored procedure here
  245.     @tableName varchar(200)
  246. ,   @anchorKey bigint
  247. ,   @changedAt datetime = NULL  -- optional
  248. ,   @MD_ID int -- new metadata id
  249. AS
  250. BEGIN
  251.     SET NOCOUNT ON;
  252.    
  253.     BEGIN TRANSACTION
  254.    
  255.     -- TODO make this proc generic.
  256.     INSERT INTO [dbo].[HISTORY_FI_RAT_FinancialInstrument_Rating]
  257.     (          
  258.             [FI_ID]
  259.            ,[FI_RAT_FinancialInstrument_Rating]
  260.            ,[FI_RAT_ChangedAt]
  261.            ,[FI_RAT_RecordedAt]
  262.            ,[FI_RAT_IsValid]
  263.            ,[Metadata_FI_RAT])
  264.     SELECT [FI_ID]
  265.           ,[FI_RAT_FinancialInstrument_Rating]
  266.           ,[FI_RAT_ChangedAt]
  267.           , m.MD_RecordedAt -- original recordedAt
  268.           ,FI_RAT_IsValid
  269.           ,@MD_ID
  270.     FROM [dbo].[FI_RAT_FinancialInstrument_Rating] r
  271.     INNER JOIN MD_MetaData m on m.MD_ID = r.Metadata_FI_RAT
  272.     WHERE r.FI_ID = @anchorKey
  273.         and r.FI_RAT_ChangedAt = @changedAt
  274.  
  275.     DELETE FROM FI_RAT_FinancialInstrument_Rating
  276.     WHERE FI_ID = @anchorKey
  277.         and FI_RAT_ChangedAt = @changedAt
  278.  
  279.     COMMIT TRANSACTION
  280.        
  281. END
  282. GO
  283.  
  284. -- create one financial instrument
  285. truncate table  [FI_FinancialInstrument]
  286. truncate table  FI_RAT_FinancialInstrument_Rating
  287. truncate table  HISTORY_FI_RAT_FinancialInstrument_Rating
  288. truncate table MD_MetaData
  289.  
  290. insert into MD_MetaData values(41, '2011-03-17')
  291. insert into FI_FinancialInstrument (Metadata_FI) values (41);
  292.  
  293.  
  294. -- we should have no information whatsoever yet
  295. select * from FI_RAT_FinancialInstrument_Rating;
  296. select * from llFI_FinancialInstrument;
  297.  
  298. -- DAY 1
  299. -- insert the first ratings for the created financial instrument
  300. insert into MD_MetaData values(42, '2011-03-17')
  301. insert into FI_RAT_FinancialInstrument_Rating
  302. values (1, 'A', '2011-03-17', 1, 42);
  303. insert into FI_RAT_FinancialInstrument_Rating
  304. values (1, '?', '2011-03-19', 1, 42);
  305.  
  306. -- all rows in the attribute table
  307. select * from FI_RAT_FinancialInstrument_Rating;
  308.  
  309. -- the latest view
  310. select * from llFI_FinancialInstrument;
  311. -- every day of the week in the test along changing time
  312. select * from plFI_FinancialInstrument('2011-03-15');
  313. select * from plFI_FinancialInstrument('2011-03-16');
  314. select * from plFI_FinancialInstrument('2011-03-17');
  315. select * from plFI_FinancialInstrument('2011-03-18');
  316. select * from plFI_FinancialInstrument('2011-03-19');
  317. select * from plFI_FinancialInstrument('2011-03-20');
  318.  
  319. -- DAY 2
  320. -- Note that the following requires user knowledge of existing data
  321. -- A rating become B rating starting from 03-16
  322. -- first retract old A rating
  323. insert into MD_MetaData values(43, '2011-03-18')
  324.  
  325. exec retract 'FI_RAT_FinancialInstrument_Rating', 1,  '2011-03-17' , 43
  326.  
  327. select * from h_FI_RAT_FinancialInstrument_Rating
  328.  
  329. insert into FI_RAT_FinancialInstrument_Rating
  330. values (1, 'B', '2011-03-16', 1, 43);
  331. insert into FI_RAT_FinancialInstrument_Rating
  332. values (1, 'A', '2011-03-18', 1, 43);
  333.  
  334. /* It may be possible to do:
  335.  
  336. insert into FI_RAT_FinancialInstrument_Rating
  337. values (1, 'B', '[2011-03-16, 2011-03-17]', 2011-03-18, 42);
  338.  
  339. using an insert trigger, and derive the three inserts above.
  340. */
  341.  
  342. -- all rows in the attribute table
  343. select * from FI_RAT_FinancialInstrument_Rating;
  344. -- the latest view
  345. select * from llFI_FinancialInstrument;
  346. -- every day of the week in the test along changing time
  347. select * from plFI_FinancialInstrument('2011-03-15');
  348. select * from plFI_FinancialInstrument('2011-03-16');
  349. select * from plFI_FinancialInstrument('2011-03-17');
  350. select * from plFI_FinancialInstrument('2011-03-18');
  351. select * from plFI_FinancialInstrument('2011-03-19');
  352. select * from plFI_FinancialInstrument('2011-03-20');
  353. -- some interesting intersections
  354. select * from ppFI_FinancialInstrument('2011-03-17', '2011-03-17');
  355. select * from ppFI_FinancialInstrument('2011-03-17', '2011-03-18');
  356.  
  357. -- DAY 3
  358. insert into MD_MetaData values(44, '2011-03-19')
  359.  
  360. exec retract 'FI_RAT_FinancialInstrument_Rating', 1, '2011-03-16',44
  361. exec retract 'FI_RAT_FinancialInstrument_Rating', 1, '2011-03-18',44
  362. exec retract 'FI_RAT_FinancialInstrument_Rating', 1, '2011-03-19',44
  363. insert into FI_RAT_FinancialInstrument_Rating
  364. values (1, 'C', '2011-03-15', 1, 44);
  365. insert into FI_RAT_FinancialInstrument_Rating
  366. values (1, '?', '2011-03-20', 1, 44);
  367.  
  368. -- all rows in the attribute table
  369. select * from h_FI_RAT_FinancialInstrument_Rating order by 4;
  370. select * from FI_RAT_FinancialInstrument_Rating order by 4;
  371. -- the latest view
  372. select * from llFI_FinancialInstrument;
  373. -- every day of the week in the test along changing time
  374. select * from plFI_FinancialInstrument('2011-03-15');
  375. select * from plFI_FinancialInstrument('2011-03-16');
  376. select * from plFI_FinancialInstrument('2011-03-17');
  377. select * from plFI_FinancialInstrument('2011-03-18');
  378. select * from plFI_FinancialInstrument('2011-03-19');
  379. select * from plFI_FinancialInstrument('2011-03-20');
  380. -- some interesting intersections
  381. select * from ppFI_FinancialInstrument('2011-03-17', '2011-03-17');
  382. select * from ppFI_FinancialInstrument('2011-03-17', '2011-03-18');
  383. select * from ppFI_FinancialInstrument('2011-03-17', '2011-03-19');
  384.  
  385. -- DAY 4
  386. insert into MD_MetaData values(45, '2011-03-20')
  387.  
  388. exec retract 'FI_RAT_FinancialInstrument_Rating', 1, '2011-03-20',45
  389.  
  390. insert into FI_RAT_FinancialInstrument_Rating
  391. values (1, 'D', '2011-03-17',  1, 45);
  392.  
  393. -- all rows in the attribute table
  394. select * from h_FI_RAT_FinancialInstrument_Rating;
  395. -- the latest view
  396. select * from llFI_FinancialInstrument;
  397. -- every day of the week in the test along changing time
  398. select * from plFI_FinancialInstrument('2011-03-15');
  399. select * from plFI_FinancialInstrument('2011-03-16');
  400. select * from plFI_FinancialInstrument('2011-03-17');
  401. select * from plFI_FinancialInstrument('2011-03-18');
  402. select * from plFI_FinancialInstrument('2011-03-19');
  403. select * from plFI_FinancialInstrument('2011-03-20');
  404. -- some interesting intersections
  405. select * from ppFI_FinancialInstrument('2011-03-17', '2011-03-17');
  406. select * from ppFI_FinancialInstrument('2011-03-17', '2011-03-18');
  407. select * from ppFI_FinancialInstrument('2011-03-17', '2011-03-19');
  408. select * from ppFI_FinancialInstrument('2011-03-17', '2011-03-20');
  409.  
  410.  
  411. -- DAY 5
  412. insert into MD_MetaData values(46, '2011-03-21')
  413.  
  414. insert into FI_RAT_FinancialInstrument_Rating
  415. values (1, 'E', '2011-03-18',  1, 46);
  416. insert into FI_RAT_FinancialInstrument_Rating
  417. values (1, 'D', '2011-03-20',  1, 46);
  418.  
  419. -- all rows in the attribute table
  420. select * from h_FI_RAT_FinancialInstrument_Rating;
  421. -- the latest view
  422. select * from llFI_FinancialInstrument;
  423. -- every day of the week in the test along changing time
  424. select * from plFI_FinancialInstrument('2011-03-15');
  425. select * from plFI_FinancialInstrument('2011-03-16');
  426. select * from plFI_FinancialInstrument('2011-03-17');
  427. select * from plFI_FinancialInstrument('2011-03-18');
  428. select * from plFI_FinancialInstrument('2011-03-19');
  429. select * from plFI_FinancialInstrument('2011-03-20');
  430. -- some interesting intersections
  431. select * from ppFI_FinancialInstrument('2011-03-18', '2011-03-20');
  432. select * from ppFI_FinancialInstrument('2011-03-18', '2011-03-21');
  433. select * from ppFI_FinancialInstrument('2011-03-19', '2011-03-20');
  434. select * from ppFI_FinancialInstrument('2011-03-19', '2011-03-21');
  435.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement