4

我正在尝试在下面的查询中创建一个简单的索引视图。但是,当我尝试在其上创建唯一聚集索引时,出现以下错误:

无法在视图“..”上创建聚集索引“..”,因为视图的选择列表包含聚合函数或分组列的结果表达式。考虑从选择列表中删除聚合函数或分组列的结果表达式。

我使用的查询如下:

SELECT 
    [Manufacturer]
    ,ISNULL(SUM([QAV]),0) as AvgQAV
    ,ISNULL(SUM([BackOrders$]),0)as AvgBackorder$
    ,DATEPART(year,[Date])as Year
    ,DATEPART(month,[Date])as Month
    ,[fixSBU]
    ,[DC Name]
FROM [dbo].[TABLE1]
Group By
    [Manufacturer]      
    ,DATEPART(year,[Date])
    ,DATEPART(month,[Date])
    ,[fixSBU]
    ,[DC Name]

谁能告诉我这可能的原因?如您所见,我已经在使用该ISNULL功能。

4

4 回答 4

5

这是索引视图的所有限制的链接:https ://msdn.microsoft.com/en-us/library/ms191432.aspx#Restrictions

从文档中这两个项目应该突出:

  • 如果存在 GROUP BY,则 VIEW 定义必须包含 COUNT_BIG(*) 并且不得包含 HAVING。这些 GROUP BY 限制仅适用于索引视图定义。即使查询不满足这些 GROUP BY 限制,查询也可以在其执行计划中使用索引视图。
  • 如果视图定义包含 GROUP BY 子句,则唯一聚集索引的键只能引用 GROUP BY 子句中指定的列。

此外,您需要更改您的 ISNULL 语句。现在你有 ISNULL(SUM([BackOrders$]),0),它应该是 SUM(ISNULL([BackOrders$], 0))。您需要对 ISNULL 求和,而不是相反。

于 2015-03-24T01:50:15.653 回答
0

没有多大意义(至少对我来说不是),但参考:https ://msdn.microsoft.com/en-us/library/ms191432.aspx

具体来说:

如果存在 GROUP BY,则 VIEW 定义必须包含 COUNT_BIG(*) 并且不得包含 HAVING。这些 GROUP BY 限制仅适用于索引视图定义。即使查询不满足这些 GROUP BY 限制,查询也可以在其执行计划中使用索引视图。

尝试将 a 添加COUNT_BIG(*)到您的选择列表中并试一试。

于 2015-03-24T01:38:31.060 回答
0

我有一个类似的问题。我的选择字段之一如下所示:

sum(Pa * (CTRatio1a/CTRatio2a) * (VTRatio1/VTRatio2)* Polarity * [Percentage])/1000.0

通过在括号中包含最后一个除以 1000,它解决了问题:

sum(Pa * (CTRatio1a/CTRatio2a) * (VTRatio1/VTRatio2)* Polarity * [Percentage]/1000.0)
于 2016-02-18T16:31:00.087 回答
0

提示:数据库中最好有一个真实的日期字段,而不仅仅是年/月。这样,除了聚集索引之外,您还可以创建日期索引。

但是,如果你有FullDate,你会得到同样的错误信息。YearMonthview contains an expression on result of aggregate function or grouping column

如果您这样做,可能会发生该错误:

SELECT 

    [Manufacturer]  
    ,[Date] as FullDate
    ,DATEPART(year,[Date]) as Year
    ,DATEPART(month,[Date]) as Month

    ,COUNT_BIG(*) as Count
    ,SUM(OrderValue) as TotalOrderValue

FROM [dbo].[TABLE1]
Group By

    [Manufacturer]      

    ,[Date]
    ,DATEPART(year,[Date])
    ,DATEPART(month,[Date])

虽然不是很明显发生了什么,但我认为这是因为它Date在分组列中查看并Date在其他列中使用(对于年份和月份)。显然,尽管这在逻辑上应该可行,并且您应该能够像那样进行分组。

我发现了一个让它起作用的技巧:

SELECT 

    [Manufacturer]  
    ,DATEADD(day, 0, [Date]) as FullDate
    ,DATEPART(year,[Date])as Year
    ,DATEPART(month,[Date])as Month

    ,COUNT_BIG(*) as Count
    ,SUM(OrderValue) as TotalOrderValue

FROM [dbo].[TABLE1]
Group By

    [Manufacturer]      

    ,DATEADD(day, 0, [Date])
    ,DATEPART(year,[Date])
    ,DATEPART(month,[Date])

这诱使解析器允许它,现在我可以创建一个单独的索引(在聚集之后)以按 FullDate 搜索。

奖励:我偶然发现这个的真正原因是因为我需要计算昂贵的 ISO_WEEK 和 ISO_YEAR。这是我为此使用的分组子句的最终完整列表:

-- date
DATEADD(day, 0, [Order].OrderDateDt) as OrderDateDt, -- trick! add 0 days to date 

-- day / month / year / quarter
DATEPART(day, [Order].OrderDateDt) as OrderDate_day,
DATEPART(month, [Order].OrderDateDt) as OrderDate_month,
DATEPART(year, [Order].OrderDateDt) as OrderDate_year,
DATEPART(quarter, [Order].OrderDateDt) as OrderDate_quarter,

-- iso week
DATEPART(iso_week, [Order].OrderDateDt) as OrderDate_isoweek,
YEAR(DATEADD(day, 26 - DATEPART(iso_week, [Order].OrderDateDt), [Order].OrderDateDt)) as OrderDate_isoyear

确保在 SELECT 和 GROUP BY 中包含所有这些完全相同的内容。

于 2021-04-14T01:04:12.993 回答