If you’re getting an error that reads “Cannot create index on view “demo.dbo.vDistinctPrice” because it contains the DISTINCT keyword…” etc etc in SQL Server, it appears that you’re trying to create an index on a view that contains the DISTINCT keyword.
As the error message alludes to, this is not allowed.
To fix this issue, and as the message states, try replacing DISTINCT with GROUP BY or COUNT_BIG(*) to get the same effect. Actually, perhaps it should read “and“, as in “GROUP BY and COUNT_BIG(*)“. I say this because if we include the GROUP BY clause in an indexed view, we must also include COUNT_BIG(*). If we don’t, we get a different error. And it’s not just a matter of including the COUNT_BIG() function with any column name. It must be the asterisk wildcard (*), as in COUNT_BIG(*).
Two other options include omitting DISTINCT from the view altogether (if possible), and just not indexing the view.
Example of Error
Suppose we create a simple view like this:
CREATE VIEW vDistinctPrice WITH SCHEMABINDING AS
SELECT
DISTINCT Price
FROM dbo.Sales;
That view contains the DISTINCT keyword.
Now let’s try to create an index against that view:
CREATE UNIQUE CLUSTERED INDEX IDX_DistinctPrice ON vDistinctPrice (Price);
Output:
Msg 10100, Level 16, State 1, Line 1
Cannot create index on view "demo.dbo.vDistinctPrice" because it contains the DISTINCT keyword. Consider removing DISTINCT from the view or not indexing the view. Alternatively, consider replacing DISTINCT with GROUP BY or COUNT_BIG(*) to simulate DISTINCT on grouping columns.
As the message tells us, the DISTINCT keyword is causing a problem.
Solutions
Here are three solutions:
- Don’t index the view.
- Remove the
DISTINCTkeyword altogether. But that assumes the query can do without it. - Replace
DISTINCTwithGROUP BYandCOUNT_BIG(*)to get the same effect.
The first two are straight forward and self-explanatory, so let’s look at the third option.
Here’s an example of replacing DISTINCT with the GROUP BY clause along with COUNT_BIG(*) to achieve the same effect that the DISTINCT clause was providing:
ALTER VIEW vDistinctPrice WITH SCHEMABINDING AS
SELECT
Price,
COUNT_BIG(*) AS Count
FROM dbo.Sales
GROUP BY Price;
Now we can create the index:
CREATE UNIQUE CLUSTERED INDEX IDX_DistinctPrice ON vDistinctPrice (Price);
Output:
Commands completed successfully.
This time it worked.
As mentioned, it must be COUNT_BIG(*) with the asterisk wildcard. Also, don’t forget to provide a column alias for the COUNT_BIG(*) column, otherwise you’ll get another error.