2009-07-17 2 views
0

Я пытаюсь выполнить управление версиями строк с помощью индексированного представления, группировки записей по их ключу и временной метке и записи максимальной (отметки времени). Это хорошо, но запрос, который я использовал (см. Ниже), делает самостоятельное соединение, то есть он не может использоваться в индексированном представлении, что, я думаю, будет иметь важное значение для производительности. Есть ли способ переписать запрос, чтобы представление могло быть успешно создано с помощью SCHEMABINDING?SQL GROUP BY: Получение самой последней обновленной записи для индексированного представления

Я использую 2005, но решение только в 2008 году тоже будет хорошо.

IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[Items]')) 
    DROP VIEW [dbo].[Items] 
GO 
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ItemHistory]') AND type in (N'U')) 
    DROP TABLE [dbo].[ItemHistory] 
GO 
CREATE TABLE [dbo].[ItemHistory](
    [Key] [nchar](10) NOT NULL, 
    [Value] [int] NOT NULL, 
    [TimeStamp] Timestamp NOT NULL, 
    [LastUpdateBy] [varchar](50) NOT NULL CONSTRAINT [DF_ItemHistory_LastUpdateBy] DEFAULT (SUSER_NAME()), 
    [Deleted] BIT NOT NULL DEFAULT (0) 
    CONSTRAINT [PK_ItemHistory] PRIMARY KEY CLUSTERED 
    (
     [Key] ASC, 
     [TimeStamp] ASC 
    ) ON [PRIMARY] 
) 
GO 
CREATE VIEW dbo.Items 
--WITH SCHEMABINDING --doesnt work with the query below :(
AS 
    SELECT ih.[key], ih.[Value] FROM ItemHistory ih 
    INNER JOIN (
     SELECT [Key], Max([TimeStamp]) [TimeStamp] 
     FROM ItemHistory 
     GROUP BY [Key] 
    ) ih2 ON ih.[key] = ih2.[key] AND ih.[TimeStamp] = ih2.[TimeStamp] AND Deleted = 0 
GO 
INSERT INTO Items ([Key], [Value]) VALUES ('ItemA', 1) 
INSERT INTO Items ([Key], [Value]) VALUES ('ItemA', 2) 
INSERT INTO Items ([Key], [Value]) VALUES ('ItemA', 3) 

GO 
SELECT * FROM ItemHistory 
SELECT * FROM Items 

ответ

2

Если заменить ItemHistory с dbo.ItemHistory в определении Items зрения, он должен работать.

Также вы можете найти следующий запрос, выполняемый лучше, так как он избегает использования функции MAX.

CREATE VIEW dbo.Items 
WITH SCHEMABINDING 
AS 
    SELECT ih.[key], ih.[Value] FROM dbo.ItemHistory ih 
    WHERE NOT EXISTS (SELECT [Key] 
     FROM dbo.ItemHistory AS ih2 
     WHERE ih.[key] = ih2.[key] AND ih.[TimeStamp] < ih2.[TimeStamp]) AND Deleted = 0 
GO 
+0

Вы, сэр, гений. Я сэр, я идиот. Не прочитал сообщение create правильно. Would ВЫБРАТЬ IH. [Ключ], IH. [Value] FROM dbo.ItemHistory Ih WHERE NOT EXISTS (SELECT TOP 1 [Key] FROM dbo.ItemHistory AS IH2 WHERE IH. [Ключ] = IH2. [ key] AND ih. [TimeStamp] mcintyre321

+0

Вы слишком добры. Я не уверен, что дополнительное предложение TOP 1 сделает его быстрее, поскольку SQL Server выполняет множество оптимизаций за кулисами, и на самом деле планы выполнения идентичны. В качестве другого примера нет разницы, насколько мне известно, между использованием SELECT * и SELECT [Key] для вспомогательного запроса с точки зрения скорости выполнения, поскольку SQL Server интересуется только тем, существует или нет строка. – MikeD