请在这篇文章的底部找到所有必要的脚本来创建我在这里描述的场景。
设想:
我有一个“交易”表,我将所有交易存储在股票市场管理应用程序中。所有交易都包含相关信息,例如 TransactionType、TransactionAmount 等。
接下来的两个表非常简单且不言自明,即人员和公司。
然后,我有一个名为 TransactionsForCompanies 的表,其中存储了企业客户创建的所有交易。在这个表中,我只有两列: TransactionId -- 来自 Transactions 表 -- CompanyId -- 来自 Companies 表。
名为 TransactionsForPeople 的下一个表与上一个表几乎相同,但它用于识别个人创建的交易。
请查看数据库结构,我认为这很容易理解。
这是我正在尝试做的事情以及我需要帮助的地方。
我想创建一个视图,为人们提供“最后交易日期”。因此,如果一个人在上个月进行了多次交易,则此视图应该为我提供可能仅在 2 小时前进行交易的那个人的最后交易日期。当然,视图将返回所有“个人客户”的最后交易日期。
为此,我使用了 MAX 函数,并且视图运行良好。但是,因为我使用的是 MAX 函数,所以我无法为视图创建索引。结果,我遇到了性能问题,因为我的“事务”表有数百万条记录。
当然,这个想法是在另一个 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(0x0000A19901236069 AS DateTime), 1753.5000, N'My best offer...')
GO
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (3, N'SELL', CAST(0x0000A19901236AF5 AS DateTime), 1753.5000, N'Will take it!')
GO
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (4, N'BUY', CAST(0x0000A19901236C21 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