在日期和状态之间计数的存储过程

时间:2019-05-07 20:03:20

标签: sql-server

我需要一个在日期和状态之间进行计数的存储过程。

我有一个products表,如下所示:

ProductId(PK) ProductTypeId(FK)
-------------------------------
    1                 3
    2                 3
    3                 2
    4                 1
    5                 1

每次在此products表中插入一行,即表示已售出新产品。

我在ProductTypeId列中只有3种产品,它实际上代表一台服务器,我的客户可以取消该服务器并取消其状态或将其保持为暂停状态,这使我们可以看到状态表的历史记录像这样:

“历史记录状态表”:

StatusId(PK) ProductId(FK) StatusDate ProductStatus(FK)
1                 ,1      ,1-1-17       ,1
2                 ,1      ,2-12-17      ,2
3                 ,2      ,21-5-17       ,1
4                 ,3      ,11-5-18       ,1
5                 ,2      ,18-5-18       ,2
6                 ,2      ,10-8-18       ,3

我只有1,2,3种状态(“ ProductStatus”字段)三种。

“ StatusDate”字段代表状态更改的日期,因此,客户第一次购买产品/服务时,他/她将拥有一个永不改变的“ ProductTypeId”(1、2或3),并且“ ProductStatus”为1,但将来可以随时更改。

有时候,我的客户想取消(ProductStatus = 3)该产品/服务或保留为“保留”(ProductStatus = 2),并且发生这种情况时,新行将添加到“历史记录状态表”中,状态的日期已更改(“ StatusDate”字段)。

我的目标是计算每月(每月31号)处于状态1(有效)的ProductType

因此,如果我们有一个产品在19/1/19中处于状态1,并且状态直到19/4/19才改变,这意味着我需要在2月和3月进行计数。

存储过程的结果应类似于:

    year     month      productId(1)     productId(2)     productId(3)
    -------------------------------------------------------------------
     2017      1              0               0                 1
     2017      2              0               0                 1
     2017      3              0               0                 1
     2017      4              0               0                 1
     2017      5              0               0                 2
     2017      6              0               0                 2

以此类推。...

表结构:

CREATE TABLE [dbo].[tbl_SalesProducts]
(
    [ProductId] [int] IDENTITY(1,1) NOT NULL,
    [ProductTypeId] [tinyint] NOT NULL,

    CONSTRAINT [PK_tbl_SalesProducts] 
        PRIMARY KEY CLUSTERED ([ProductId] ASC)
                    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[tbl_SalesProductStatusHistory]
(
    [StatusId] [int] IDENTITY(1,1) NOT NULL,
    [ProductId] [int] NOT NULL,
    [StatusDate] [date] NOT NULL,
    [ProductStatus] [tinyint] NOT NULL,

    CONSTRAINT [PK_tbl_SalesProductStatus] 
        PRIMARY KEY CLUSTERED ([StatusId] ASC)
                    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

SET IDENTITY_INSERT [dbo].[tbl_SalesProducts] ON 
GO

INSERT INTO [dbo].[tbl_SalesProducts] ([ProductId], [ProductTypeId]) 
VALUES (1, 1), (2, 3), (3, 2), (4, 1), (5, 1)
GO

SET IDENTITY_INSERT [dbo].[tbl_SalesProducts] OFF
GO

SET IDENTITY_INSERT [dbo].[tbl_SalesProductStatusHistory] ON 
GO
INSERT INTO [dbo].[tbl_SalesProductStatusHistory] ([StatusId], [ProductId], [StatusDate], [ProductStatus]) 
VALUES (1, 1, CAST(N'2017-12-23' AS Date), 1),
       (2, 2, CAST(N'2018-01-02' AS Date), 1),
       (4, 1, CAST(N'2018-02-18' AS Date), 2),
       (5, 3, CAST(N'2018-03-19' AS Date), 1),
       (6, 4, CAST(N'2018-04-24' AS Date), 1),
       (7, 2, CAST(N'2018-04-07' AS Date), 3),
       (8, 5, CAST(N'2018-07-09' AS Date), 1)
GO

SET IDENTITY_INSERT [dbo].[tbl_SalesProductStatusHistory] OFF
GO

ALTER TABLE [dbo].[tbl_SalesProducts] WITH CHECK 
    ADD CONSTRAINT [FK_tbl_SalesProducts_tbl_Products] 
        FOREIGN KEY([ProductTypeId]) REFERENCES [dbo].[tbl_Products] ([MezaeeMuzar])
GO

ALTER TABLE [dbo].[tbl_SalesProducts] CHECK CONSTRAINT [FK_tbl_SalesProducts_tbl_Products]
GO

ALTER TABLE [dbo].[tbl_SalesProductStatusHistory] WITH CHECK 
    ADD CONSTRAINT [FK_tbl_SalesProductStatus_tbl_SalesProducts] 
        FOREIGN KEY([ProductId]) REFERENCES [dbo].[tbl_SalesProducts] ([ProductId])
GO

ALTER TABLE [dbo].[tbl_SalesProductStatusHistory] CHECK CONSTRAINT [FK_tbl_SalesProductStatus_tbl_SalesProducts]
GO

ALTER TABLE [dbo].[tbl_SalesProductStatusHistory] WITH CHECK 
    ADD CONSTRAINT [FK_tbl_SalesProductStatusHistory_tbl_SalesProductsStatus] 
        FOREIGN KEY([ProductStatus]) REFERENCES [dbo].[tbl_SalesProductStatus] ([MezaeeStatusMuzar])
GO

ALTER TABLE [dbo].[tbl_SalesProductStatusHistory] CHECK CONSTRAINT [FK_tbl_SalesProductStatusHistory_tbl_SalesProductsStatus]
GO

0 个答案:

没有答案