Укажите десятичную точность столбца в индексированном представлении SQL Server

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

Полный работающий пример приведен ниже:

-- drop and recreate example table and view if they exist
IF EXISTS(SELECT * FROM sys.objects WHERE name = 'ExampleIndexedView')
    DROP VIEW [dbo].[ExampleIndexedView]

IF EXISTS(SELECT * FROM sys.objects WHERE name = 'Example')
    DROP TABLE [dbo].[Example]

-- create example table
CREATE TABLE [dbo].[Example](
    [UserID] [int],
    [Amount] [decimal](9, 2)
) ON [PRIMARY]

-- insert sample rows
INSERT INTO [dbo].[Example] ([UserID], [Amount]) VALUES (1, 10)
INSERT INTO [dbo].[Example] ([UserID], [Amount]) VALUES (2, 20)
INSERT INTO [dbo].[Example] ([UserID], [Amount]) VALUES (3, 30)
INSERT INTO [dbo].[Example] ([UserID], [Amount]) VALUES (1, 15)
INSERT INTO [dbo].[Example] ([UserID], [Amount]) VALUES (1, 2.5)
GO

-- create indexed view
CREATE VIEW [dbo].[ExampleIndexedView]
WITH SCHEMABINDING
AS

SELECT
    e.UserID as UserID
    ,SUM(ISNULL(e.[Amount], 0)) as [Amount]
    ,COUNT_BIG(*) as [Count]        --Required for indexed views
FROM [dbo].[Example] e
GROUP BY 
    e.UserID
GO

CREATE UNIQUE CLUSTERED INDEX [CI_ExampleIndexedView]
    ON [dbo].[ExampleIndexedView]
        ([UserID])

-- show stats for view
exec sp_help [ExampleIndexedView]

Это приводит к представлению со столбцами:

UserID(int, null)  
Amount(decimal(38,2), null)  

Я понимаю, почему представление будет автоматически использовать максимально возможный тип хранилища для столбца SUM, однако, скажем, я знаю, что суммирование этого столбца Amount никогда не превысит пределы decimal(19, 2) - есть ли способ заставить представление создать столбец как decimal(19, 2) вместо decimal(38, 2)?

decimal(38, 2) занимает 17 байт для хранения, decimal(19,2) занимает только 9 байт. В качестве теста я продублировал свое индексированное представление в обычную таблицу, где я использовал decimal(19,2), и общая экономия места для хранения составила около 40%, поэтому кажется, что это стоит сделать для представления, которое содержит большое количество десятичных агрегаций. .

Изменить: Опубликован полный готовый к запуску пример, который создает примерную таблицу, заполняет ее несколькими строками, а затем создает индексированное представление для этой таблицы. В результате столбец Amount в индексированном представлении является десятичным (38,2), я хотел бы найти способ заставить его быть десятичным (19,2) по причинам экономии места.


person Craig    schedule 13.09.2017    source источник


Ответы (1)


CAST() или CONVERT() с требуемой точностью

Select 
    UserID, 
    CONVERT(DECIMAL(9,2), SUM(Amount)) as Amount, 
FROM 
    Example
GROUP BY 
    UserID
person Squirrel    schedule 13.09.2017
comment
Это не имеет никакого значения, индексированное представление по-прежнему создает столбец с максимально возможной десятичной точностью. - person Craig; 13.09.2017
comment
в моем тесте я получаю (9,2) - person Squirrel; 13.09.2017
comment
какую версию Sql Server вы используете? я использую SQL Server 2014. - person Craig; 13.09.2017
comment
Мне кажется, что вы создаете обычное представление, а не индексированное представление, поскольку ваш синтаксис неверен для индексированного представления. Если я делаю это как обычное представление, то вы правы, тип столбца корректируется соответствующим образом, но это не относится к индексированному представлению. Я обновлю свой OP, включив в него сценарий создания полного индексированного представления. - person Craig; 13.09.2017
comment
О, я не создавал индекс, просто привязывая представление. Только что попробовал, с convert() не позволяет создать индекс. Но тип данных представления (9,2).exec sp_help [ExampleIndexedView] - person Squirrel; 13.09.2017
comment
Это не для меня. Column_name Type Computed Length Prec Scale Nullable TrimTrailingBlanks FixedLenNullInSource Collation UserID int no 4 10 0 yes (n/a) (n/a) NULL Amount decimal no 17 38 2 yes (n/a) (n/a) NULL Count bigint no 8 19 0 yes (n/a) (n/a) NULL извините, не знаю, как правильно отформатировать это в комментарии. Можете ли вы запустить мое точное создание представления и посмотреть, что вы получите. Между тем, что вы делаете, должна быть какая-то разница. - person Craig; 13.09.2017
comment
или опубликуйте свой запрос на создание представления + индекса в своем ответе, и я попробую его на своем ПК и посмотрю, что я получу. - person Craig; 13.09.2017
comment
Я обновил свой OP, включив в него полный пример сценария, который можно запустить, чтобы продемонстрировать проблему. Мне было бы интересно посмотреть, делает ли он то же самое для вас, учитывая, что, как вы сказали, вы получаете другой результат с образцом, который вы сделали. - person Craig; 18.09.2017