Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.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 如何在数据库中创建通行证持有人信息的移动快照_Sql_Sql Server_Tsql_Database Design - Fatal编程技术网

Sql 如何在数据库中创建通行证持有人信息的移动快照

Sql 如何在数据库中创建通行证持有人信息的移动快照,sql,sql-server,tsql,database-design,Sql,Sql Server,Tsql,Database Design,我有一个会员数据库,我想在其中创建一个附加表,以跟踪我们的会员资格在整整12个月内如何随时间(按月)变化。我不确定使用哪种数据库设计最好 我们的会员有开始日期和结束日期的订阅。每个月我们都会有一些新会员,也就是说,他们的订阅开始日期就在那个月。同样,每个月我们都会有一些会员离开,也就是说,他们的订阅截止日期就在那个月。对于我们剩余的会员,他们在整个月内都是最新的,即他们的认购开始日期在给定的月份之前,而他们的认购结束日期在给定的月份之后 我在我创建的表中有这些数据: SubscriptionSn

我有一个会员数据库,我想在其中创建一个附加表,以跟踪我们的会员资格在整整12个月内如何随时间(按月)变化。我不确定使用哪种数据库设计最好

我们的会员有开始日期和结束日期的订阅。每个月我们都会有一些新会员,也就是说,他们的订阅开始日期就在那个月。同样,每个月我们都会有一些会员离开,也就是说,他们的订阅截止日期就在那个月。对于我们剩余的会员,他们在整个月内都是最新的,即他们的认购开始日期在给定的月份之前,而他们的认购结束日期在给定的月份之后

我在我创建的表中有这些数据:

SubscriptionSnaphot
   MemberID int
   SubscriptionType varchar
   StartDate datetime
   EndDate datetime
如果成员具有多个订阅,则该成员可以在数据中出现多次

我想补充一下这个表格,包括这个成员过去12个月的状态。例如,假设一名成员在9个月前加入,持有6个月的通行证,然后离开。他们在过去12个月的状态为:I、I、I、N、C、C、C、C、E、I、I,其中I=不活动,N=新,C=当前,E=过期

一个简单的设计可能只是向我的表中添加12列,过去12个月中每一列,然后使用一些查询更新它们

我的问题是:

  • 表示此移动快照的好设计是什么
  • 填写快照数据的相应查询是什么(假设您拥有如上所述的订阅数据)
我没有处理大量数据,也不需要完全标准化的设计。我想要的是一种简单的创建和提取数据的方法。在过去的12个月中,我可能会在每个月的第一天重新生成这些数据


我使用的是SQL Server 2008,但如果可能的话,我更喜欢不依赖数据库的解决方案。

我会编写一个表,它是您的成员表的克隆,但没有不相关的信息。
我将继续使用aspnet_会员表,因为它是相当有名的。 让我们称之为“asp\U成员资格\U审计”

我会创建一个表格,你可以把一个独特的邮戳(一次)。 让我们称之为“Tageroni”(Tag的长名称) 然后,我将向asp_Membership_Audit表中添加一列,该列是Tageroni表PK的FK

然后,每月运行一次作业,在Tageroni表中抛出一行。 然后用Tageroni FK复制您的成员表(转到aspnet_membership_Audit表)。您可以将日期戳放在“audit”表中,但我不喜欢使用时间戳作为唯一标识符……我更喜欢使用int、bigint或uuid

然后您就有了生成报告所需的数据。如果你现在想出一些“超级聪明”的东西,你的需求可能会改变。但是完全正确地捕获审计数据,您可以随时使用单列管道值创建“报告”

这是一个概念。我的查询充其量只是初步的,但只要捕获了数据,就可以稍后创建报告

但基本上,通过Tageroni表和clone表,您将获得“我的数据在任何月份的第一个月是什么样子的”的完美快照

编辑-------------

这里有一个“滑动”警告

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

最后,我创建了第二个表来保存快照信息和原始表。对后者进行了修改,添加了一个RecordID列作为前者的主键和外键。我的附加(以前的)表如下所示:

SubScriptionSnapshotData
    SubscriptionRecordID int
    Year smallint
    YearElement smallint
    ElementType varchar(15)
    Status varchar(15)
因此,此表中的每条记录都指向原始表中的一条记录,并记录其移动快照信息。基本上,我可以在快照中记录快照的年份和月份以及订阅的状态


通过使用(YearElement,ElementType)而不是简单的月份,我可以按月份、周或其他任何方式创建快照。例如,四月表示为(4,'月')。第32周的快照可以表示为(32,'周')。状态仅为“新建”、“过期”或“当前”。

您希望结果是什么样的:12列,每个列一个字符,还是一个逗号分隔的列表?当会员订阅、失效和重新升级时会发生什么?他们是否有多行具有相同的
MemberId
?我希望每个月在结果中有一列,因为select查询更容易编写。一个成员在数据库中可以有多行,每个订阅一行。(我将更新问题以反映这一点。)//我追求的是一种简单的创建和提取数据的方法//不必粗鲁,但在我多年的开发过程中,它被认为是“聪明”甚至“可爱”。。。。。。。。。。。后来,“聪明”变成了“那家伙在想什么?”很多次。你有什么发现吗?在我使用[IsApproved][bit]NOT NULL、[IsLockedOut][bit]NOT NULL的地方,你会使用SubscriptionType varchar StartDate datetime EndDate datetime如果你不需要的话,你可以删除13个月以上的数据。
SubScriptionSnapshotData
    SubscriptionRecordID int
    Year smallint
    YearElement smallint
    ElementType varchar(15)
    Status varchar(15)