2013-04-08 43 views
0

請在這篇文章的底部找到所有必要的腳本來創建我在這裏描述的場景。返回最後交易日期的SQL視圖

場景:

我有一個「交易」表,其中我存儲在A股市場的管理應用程序的所有交易。所有交易都與相關信息一起存在,例如TransactionType,TransactionAmount等。

接下來的兩個表格非常簡單並且自我解釋,即人員和公司。

然後我有一個名爲TransactionsForCompanies的表,其中存儲了企業客戶創建的所有交易。在這張表中,我只有兩列:TransactionId - 來自Transactions表 - CompanyId - 來自Companies表。

下一張名爲TransactionsForPeople的表與上一張表幾乎完全相同,但它用於識別由個人創建的交易。

請參閱數據庫結構,我認爲它會很容易理解。

這是我正在嘗試做的事以及我需要幫助的地方。

我想創建一個視圖,爲我提供「最後交易日期」給人。所以如果一個人在上個月有多次交易,這個視圖應該給我最近一次交易的日期,這個人可能在2小時前進行了交易。當然,該視圖將返回所有「個人客戶」的最後交易日期。

要做到這一點,我使用MAX函數和視圖很好地工作。但是,因爲我正在使用MAX函數,所以無法爲視圖創建索引。因此,我有一個性能問題,因爲我的「Transactions」表有數百萬條記錄。

當然,這個想法是在另一個SELECT語句中使用視圖,以便我可以生成有關大多數和最少活動客戶端的良好報告。這個SELECT語句運行速度非常慢,當我查看執行計劃時,瓶頸是我將JOIN加入到使用MAX函數的視圖中。

問題:我如何捕捉最後一個TransactionDate,以便讓人們以某種​​方式爲我提供良好的性能?

謝謝...

USE [TestDb] 
GO 
/****** Object: Table [dbo].[Companies] Script Date: 4/7/2013 1:48:18 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[Companies](
    [CompanyId] [int] IDENTITY(1,1) NOT NULL, 
    [CompanyName] [nvarchar](50) NOT NULL, 
CONSTRAINT [PK_Companies] PRIMARY KEY CLUSTERED 
(
    [CompanyId] 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 
/****** Object: Table [dbo].[People] Script Date: 4/7/2013 1:48:18 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[People](
    [PersonId] [int] IDENTITY(1,1) NOT NULL, 
    [FirstName] [nvarchar](20) NOT NULL, 
    [MiddleName] [nvarchar](20) NULL, 
    [LastName] [nvarchar](20) NOT NULL, 
CONSTRAINT [PK_People] PRIMARY KEY CLUSTERED 
(
    [PersonId] 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 
/****** Object: Table [dbo].[Transactions] Script Date: 4/7/2013 1:48:18 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[Transactions](
    [TransactionId] [int] IDENTITY(1,1) NOT NULL, 
    [TransactionType] [nvarchar](50) NOT NULL, 
    [TransactionTimeStamp] [datetime] NOT NULL, 
    [TransactionAmount] [money] NOT NULL, 
    [Comments] [nvarchar](50) NULL, 
CONSTRAINT [PK_Transactions] PRIMARY KEY CLUSTERED 
(
    [TransactionId] 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 
/****** Object: Table [dbo].[TransactionsForCompanies] Script Date: 4/7/2013 1:48:18 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[TransactionsForCompanies](
    [TransactionId] [int] NOT NULL, 
    [CompanyId] [int] NOT NULL, 
CONSTRAINT [PK_TransactionsForCompanies] PRIMARY KEY CLUSTERED 
(
    [TransactionId] ASC, 
    [CompanyId] 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 
/****** Object: Table [dbo].[TransactionsForPeople] Script Date: 4/7/2013 1:48:18 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[TransactionsForPeople](
    [TransactionId] [int] NOT NULL, 
    [PersonId] [int] NOT NULL, 
CONSTRAINT [PK_TransactionsForPeople] PRIMARY KEY CLUSTERED 
(
    [TransactionId] ASC, 
    [PersonId] 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].[Companies] ON 

GO 
INSERT [dbo].[Companies] ([CompanyId], [CompanyName]) VALUES (1, N'Company A') 
GO 
INSERT [dbo].[Companies] ([CompanyId], [CompanyName]) VALUES (2, N'Company B') 
GO 
INSERT [dbo].[Companies] ([CompanyId], [CompanyName]) VALUES (3, N'Company C') 
GO 
SET IDENTITY_INSERT [dbo].[Companies] OFF 
GO 
SET IDENTITY_INSERT [dbo].[People] ON 

GO 
INSERT [dbo].[People] ([PersonId], [FirstName], [MiddleName], [LastName]) VALUES (1, N'John', NULL, N'Doe') 
GO 
INSERT [dbo].[People] ([PersonId], [FirstName], [MiddleName], [LastName]) VALUES (2, N'Jane', NULL, N'Smith') 
GO 
INSERT [dbo].[People] ([PersonId], [FirstName], [MiddleName], [LastName]) VALUES (3, N'Betsy', NULL, N'Green') 
GO 
SET IDENTITY_INSERT [dbo].[People] OFF 
GO 
SET IDENTITY_INSERT [dbo].[Transactions] ON 

GO 
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (1, N'BUY', CAST(0x0000A1990122F5C4 AS DateTime), 300.0000, N'Got it!') 
GO 
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (2, N'BID', CAST(0x0000A199AS DateTime), 1753.5000, N'My best offer...') 
GO 
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (3, N'SELL', CAST(0x0000A199AF5 AS DateTime), 1753.5000, N'Will take it!') 
GO 
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (4, N'BUY', CAST(0x0000A199C21 AS DateTime), 1753.5000, N'Finalize purchase.') 
GO 
SET IDENTITY_INSERT [dbo].[Transactions] OFF 
GO 
INSERT [dbo].[TransactionsForCompanies] ([TransactionId], [CompanyId]) VALUES (3, 1) 
GO 
INSERT [dbo].[TransactionsForPeople] ([TransactionId], [PersonId]) VALUES (1, 2) 
GO 
INSERT [dbo].[TransactionsForPeople] ([TransactionId], [PersonId]) VALUES (2, 3) 
GO 
INSERT [dbo].[TransactionsForPeople] ([TransactionId], [PersonId]) VALUES (4, 3) 
GO 
ALTER TABLE [dbo].[Transactions] ADD CONSTRAINT [DF_Transactions_TransactionTimeStamp] DEFAULT (getutcdate()) FOR [TransactionTimeStamp] 
GO 
ALTER TABLE [dbo].[TransactionsForCompanies] WITH CHECK ADD CONSTRAINT [FK_TransactionsForCompanies_Companies] FOREIGN KEY([CompanyId]) 
REFERENCES [dbo].[Companies] ([CompanyId]) 
GO 
ALTER TABLE [dbo].[TransactionsForCompanies] CHECK CONSTRAINT [FK_TransactionsForCompanies_Companies] 
GO 
ALTER TABLE [dbo].[TransactionsForCompanies] WITH CHECK ADD CONSTRAINT [FK_TransactionsForCompanies_Transactions] FOREIGN KEY([TransactionId]) 
REFERENCES [dbo].[Transactions] ([TransactionId]) 
GO 
ALTER TABLE [dbo].[TransactionsForCompanies] CHECK CONSTRAINT [FK_TransactionsForCompanies_Transactions] 
GO 
ALTER TABLE [dbo].[TransactionsForPeople] WITH CHECK ADD CONSTRAINT [FK_TransactionsForPeople_People] FOREIGN KEY([PersonId]) 
REFERENCES [dbo].[People] ([PersonId]) 
GO 
ALTER TABLE [dbo].[TransactionsForPeople] CHECK CONSTRAINT [FK_TransactionsForPeople_People] 
GO 
ALTER TABLE [dbo].[TransactionsForPeople] WITH CHECK ADD CONSTRAINT [FK_TransactionsForPeople_Transactions] FOREIGN KEY([TransactionId]) 
REFERENCES [dbo].[Transactions] ([TransactionId]) 
GO 
ALTER TABLE [dbo].[TransactionsForPeople] CHECK CONSTRAINT [FK_TransactionsForPeople_Transactions] 
GO 

回答

0

你不會是能夠創建一個索引視圖,如果你想使用max(),正如你所說。

如何或者:

(ⅰ)變更主鍵被非聚集,然後在添加TransactionTimestamp聚簇索引爲Transactions表?

(ii)在Transactions表上添加TransactionId, TransactionTimestamp上的索引。

+0

不,您提供的想法只適用於特定情況。 我想要一個可以配合所有想法的大概。 – vishal 2013-04-08 09:16:28

+0

一般的想法是索引。您將無法在您的要求中使用索引視圖。 – muhmud 2013-04-08 09:21:29

+0

這是你的意見,但可能有解決這個問題的方法,這就是爲什麼我發佈的問題,以便我可以讓不同的人給我不同的想法。 – vishal 2013-04-08 09:51:04