我会写一个表,它是您的 Membership 表的克隆,但删除了不相关的信息。
我要背着 aspnet_Membership 表,因为它是众所周知的。我们称之为“asp_Membership_Audit”。
我会创建一个表格,您可以在其中放置一个唯一的日期戳(一次)。我们称它为“Tageroni”(“Tag”的长名称)然后我将在我的 asp_Membership_Audit 表中添加一个列,该列是 Tageroni 表的 PK 的 FK。
然后,每个月运行一次将一行放入 Tageroni 表的作业。然后使用 Tageroni FK 复制您的成员资格表(到 aspnet_Membership_Audit 表)。您可以将日期戳放在“审计”表中,但我不喜欢使用时间戳作为唯一标识符......我喜欢 int、bigint 或 uuid。
然后,您就拥有了生成报告所需的数据。如果你现在想出一些“超级聪明”的东西,你的需求可能会改变。但是完全正确地捕获审计数据,您可以随时使用单列管道值创建“报告”。
这是概念。我的查询充其量只是初步结束,但只要捕获了数据,您就可以稍后创建报告。
但基本上,使用 Tageroni 表和克隆表,您将拥有“我的数据在任何月份的第一个月的样子”的完美快照......。
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[aspnet_Membership_Audit]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
DROP TABLE [dbo].[aspnet_Membership_Audit]
END
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Tageroni]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
DROP TABLE [dbo].[Tageroni]
END
GO
CREATE TABLE [dbo].[Tageroni] (
TageroniUUID [uniqueidentifier] not null default NEWSEQUENTIALID() ,
TageroniName varchar(64) not null ,
TageroniDateStamp datetime not null
)
GO
ALTER TABLE dbo.Tageroni ADD CONSTRAINT PK_Tageroni_TageroniUUID
PRIMARY KEY CLUSTERED (TageroniUUID)
GO
ALTER TABLE dbo.Tageroni ADD CONSTRAINT CK_Tageroni_TageroniName_UNIQUE
UNIQUE (TageroniName)
GO
CREATE TABLE [dbo].[aspnet_Membership_Audit](
aspnet_Membership_Audit_UUID [uniqueidentifier] not null default NEWSEQUENTIALID() ,
TageroniUUID [uniqueidentifier] NOT NULL,
/* The 3 columns below are the User, and the "status" flags I'm interested in */
[UserId] [uniqueidentifier] NOT NULL,
[IsApproved] [bit] NOT NULL,
[IsLockedOut] [bit] NOT NULL
)
GO
ALTER TABLE dbo.aspnet_Membership_Audit ADD CONSTRAINT PK_aspnet_Membership_Audit_UUID
PRIMARY KEY CLUSTERED (aspnet_Membership_Audit_UUID)
GO
ALTER TABLE [dbo].[aspnet_Membership_Audit] WITH CHECK ADD FOREIGN KEY([TageroniUUID])
REFERENCES [dbo].[Tageroni] ([TageroniUUID])
GO
/* Once a Month, Run something like this */
INSERT INTO dbo.Tageroni ( TageroniUUID , TageroniName , TageroniDateStamp )
select '11111111-1111-1111-1111-111111111111' , 'My First Tag, 2013' , '01/01/2013'
UNION ALL select '22222222-2222-2222-2222-222222222222' , 'My Second Tag, 2013' , '02/01/2013'
UNION ALL select '33333333-3333-3333-3333-333333333333' , 'My Third Tag, 2013' , '03/01/2013'
/* Run this on Jan 1, 2013 */
INSERT INTO [dbo].[aspnet_Membership_Audit]( [UserId] , TageroniUUID , [IsApproved] , [IsLockedOut] )
Select '11111111-1111-1111-1111-111111111111' , UserId , [IsApproved] , [IsLockedOut]
from [dbo].[aspnet_Membership]
/* Run this on Feb 1, 2013 */
INSERT INTO [dbo].[aspnet_Membership_Audit]( [UserId] , TageroniUUID , [IsApproved] , [IsLockedOut] )
Select '22222222-2222-2222-2222-222222222222' , UserId , [IsApproved] , [IsLockedOut]
from [dbo].[aspnet_Membership]
/* Run this on March 1, 2013 */
INSERT INTO [dbo].[aspnet_Membership_Audit]( [UserId] , TageroniUUID , [IsApproved] , [IsLockedOut] )
Select '33333333-3333-3333-3333-333333333333' , UserId , [IsApproved] , [IsLockedOut]
from [dbo].[aspnet_Membership]
GO
Select derivedJan.UserId , derivedJan.[IsApproved] as JanIsApproved , derivedFeb.[IsApproved] as FebIsApproved , derivedMarch.[IsApproved] as MarIsApproved
From
(select * from [dbo].[aspnet_Membership_Audit] where TageroniUUID = '11111111-1111-1111-1111-111111111111') derivedJan
join
(select * from [dbo].[aspnet_Membership_Audit] where TageroniUUID = '22222222-2222-2222-2222-222222222222') derivedFeb
on derivedJan.UserId = derivedFeb.UserId
join
(select * from [dbo].[aspnet_Membership_Audit] where TageroniUUID = '33333333-3333-3333-3333-333333333333') derivedMarch
on derivedJan.UserId = derivedMarch.UserId
编辑 - - - - - - -
这是一个“滑动”警告............
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[aspnet_Membership_Audit]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
DROP TABLE [dbo].[aspnet_Membership_Audit]
END
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Tageroni]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
DROP TABLE [dbo].[Tageroni]
END
GO
CREATE TABLE [dbo].[Tageroni] (
TageroniUUID [uniqueidentifier] not null default NEWSEQUENTIALID() ,
TageroniName varchar(64) not null ,
TageroniDateStamp datetime not null ,
TageroniMonthsIntoThePast int not null
)
GO
ALTER TABLE dbo.Tageroni ADD CONSTRAINT PK_Tageroni_TageroniUUID
PRIMARY KEY CLUSTERED (TageroniUUID)
GO
ALTER TABLE dbo.Tageroni ADD CONSTRAINT CK_Tageroni_TageroniName_UNIQUE
UNIQUE (TageroniName)
GO
CREATE TABLE [dbo].[aspnet_Membership_Audit](
aspnet_Membership_Audit_UUID [uniqueidentifier] not null default NEWSEQUENTIALID() ,
TageroniUUID [uniqueidentifier] NOT NULL,
/* The 3 columns below are the User, and the "status" flags I'm interested in */
[UserId] [uniqueidentifier] NOT NULL,
[IsApproved] [bit] NOT NULL,
[IsLockedOut] [bit] NOT NULL
)
GO
ALTER TABLE dbo.aspnet_Membership_Audit ADD CONSTRAINT PK_aspnet_Membership_Audit_UUID
PRIMARY KEY CLUSTERED (aspnet_Membership_Audit_UUID)
GO
ALTER TABLE [dbo].[aspnet_Membership_Audit] WITH CHECK ADD FOREIGN KEY([TageroniUUID])
REFERENCES [dbo].[Tageroni] ([TageroniUUID])
GO
/* Once a Month, Run something like this */
/* And adjust the TageroniMonthsIntoThePast value to be a "sliding" value */
INSERT INTO dbo.Tageroni ( TageroniUUID , TageroniName , TageroniDateStamp , TageroniMonthsIntoThePast)
select '11111111-1111-1111-1111-111111111111' , 'My First Tag, 2013' , '01/01/2013' , 4
UNION ALL select '22222222-2222-2222-2222-222222222222' , 'My Second Tag, 2013' , '02/01/2013' , 3
UNION ALL select '33333333-3333-3333-3333-333333333333' , 'My Third Tag, 2013' , '01/01/2013' , 2
/* Run this on Jan 1, 2013 */
INSERT INTO [dbo].[aspnet_Membership_Audit]( [UserId] , TageroniUUID , [IsApproved] , [IsLockedOut] )
Select '11111111-1111-1111-1111-111111111111' , UserId , [IsApproved] , [IsLockedOut]
from [dbo].[aspnet_Membership]
/* Run this on Feb 1, 2013 */
INSERT INTO [dbo].[aspnet_Membership_Audit]( [UserId] , TageroniUUID , [IsApproved] , [IsLockedOut] )
Select '22222222-2222-2222-2222-222222222222' , UserId , [IsApproved] , [IsLockedOut]
from [dbo].[aspnet_Membership]
/* Run this on March 1, 2013 */
INSERT INTO [dbo].[aspnet_Membership_Audit]( [UserId] , TageroniUUID , [IsApproved] , [IsLockedOut] )
Select '33333333-3333-3333-3333-333333333333' , UserId , [IsApproved] , [IsLockedOut]
from [dbo].[aspnet_Membership]
GO
Select TwoMonthsAgoDerived.UserId , TwoMonthsAgoDerived.[IsApproved] as TwoMonthsOldIsApproved , ThreeMonthsAgoDerived.[IsApproved] as ThreeMonthsOldIsApproved , FourMonthsAgoDerived.[IsApproved] as FourMonthsOldIsApproved
From
(select aud.* from [dbo].[aspnet_Membership_Audit] aud join dbo.Tageroni tag on aud.TageroniUUID = tag.TageroniUUID where TageroniMonthsIntoThePast = 2 ) TwoMonthsAgoDerived
join
(select aud.* from [dbo].[aspnet_Membership_Audit] aud join dbo.Tageroni tag on aud.TageroniUUID = tag.TageroniUUID where TageroniMonthsIntoThePast = 3) ThreeMonthsAgoDerived
on TwoMonthsAgoDerived.UserId = ThreeMonthsAgoDerived.UserId
join (select aud.* from [dbo].[aspnet_Membership_Audit] aud join dbo.Tageroni tag on aud.TageroniUUID = tag.TageroniUUID where TageroniMonthsIntoThePast = 4) FourMonthsAgoDerived
on TwoMonthsAgoDerived.UserId = FourMonthsAgoDerived.UserId