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
DISTINCT
keyword altogether. But that assumes the query can do without it. - Replace
DISTINCT
withGROUP BY
andCOUNT_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.