メモ:create table で filtered な unique index を作る

ドキュメントの構文に載ってないけどなんか出来たのでメモ。

SQL Server での unique 制約は unique index で実現されてます。
なので、unique 制約を作る = unique index を作る です。

UNIQUE 制約を作る場合
Create Unique Constraints - SQL Server | Microsoft Docs

後から UNIQUE INDEX 作る場合
Create Unique Indexes - SQL Server | Microsoft Docs

filtered ってなんやーですが、SQL Server では index を作る時に条件指定して index を作ることが出来ます。
Create Filtered Indexes - SQL Server | Microsoft Docs

特定の状態のデータに対して index を作りたい場合に使う感じ。
これを利用すると、複数行に null が含む列に対して unique 制約を付けることも出来ます。*1

で、create table の時にまとめて作るのはドキュメントでは出来なさそうだけど、何か書けたのでメモ。
CREATE TABLE (Transact-SQL) - SQL Server | Microsoft Docs

ドキュメントに無い構文だけど、エラーが出なかったクエリ例

create table [サンプル] (
  [有効なデータでは一意なId] bigint not null, 
  [状態] nchar(2) not null,
  index [UX_サンプル_Id] unique ([有効なデータでは一意なId]) where [状態] = N'有効'
)

ドキュメントでは

< table_constraint > ::=  
[ CONSTRAINT constraint_name ]   
{   
    { PRIMARY KEY | UNIQUE }   
        [ CLUSTERED | NONCLUSTERED ]   
        (column [ ASC | DESC ] [ ,...n ] )   
        [   
            WITH FILLFACTOR = fillfactor   
           |WITH ( <index_option> [ , ...n ] )   
        ]  
        [ ON { partition_scheme_name (partition_column_name)  
            | filegroup | "default" } ]   
    | FOREIGN KEY   
        ( column [ ,...n ] )   
        REFERENCES referenced_table_name [ ( ref_column [ ,...n ] ) ]   
        [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]   
        [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]   
        [ NOT FOR REPLICATION ]   
    | CHECK [ NOT FOR REPLICATION ] ( logical_expression )  

< table_index > ::=   
{  
    {  
      INDEX index_name [ CLUSTERED | NONCLUSTERED ]   
         (column_name [ ASC | DESC ] [ ,... n ] )   
    | INDEX index_name CLUSTERED COLUMNSTORE  
    | INDEX index_name [ NONCLUSTERED ] COLUMNSTORE (column_name [ ,... n ] )  
    }  
    [ WITH ( <index_option> [ ,... n ] ) ]   
    [ ON { partition_scheme_name (column_name )   
         | filegroup_name  
         | default   
         }  
    ]   
    [ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]  

}  

ってなってるので、constraint で unique 付ける場合に where は指定出来ないとなってるし、
index の方では、unique 指定出来ないし where もダメってなってる。

普通に unique index を作る場合は、

create unique index [UX_サンプル_Id] on [サンプル] ([有効なデータでは一意なId]) where [状態] = N'有効'

って構文なので、unique の位置が変わるのは注意点?

ただ、ドキュメントに載ってないのでどのバージョンで使えるのかは動かしてみないと分からない。。
とりあえず SQL Server 2016、SQL Database v12 では動いてる。
SQL DB v12 で動いてるから、新しい SQL Server なら問題なさそう。

*1:not null を条件に付ける