Это можно сделать, создав вычисляемый столбец и поместив уникальный индекс в этот столбец.
ALTER TABLE MYTABLE
ADD COL2 AS (CASE WHEN COL1 IS NULL THEN CAST(ID AS NVARCHAR(255)) ELSE COL1 END)
CREATE UNIQUE INDEX UQ_COL2 ON MYTABLE (COL2)
Предполагается, что ID - это PK вашей таблицы, а COL1 - это столбец "уникальный или пустой".
В вычисляемом столбце (COL2) будет использоваться значение PK, если ваш «уникальный» столбец равен нулю.
В следующем примере все еще существует вероятность коллизий между столбцом ID и COL1:
ID COL1 COL2
1 [NULL] 1
2 1 1
Чтобы обойти это, я обычно создаю другой вычисляемый столбец, в котором хранится значение, полученное в COL2, из столбца ID или столбца COL1:
ALTER TABLE MYTABLE
ADD COL3 AS (CASE WHEN COL1 IS NULL THEN 1 ELSE 0 END)
Индекс должен быть изменен на:
CREATE UNIQUE INDEX UQ_COL2 ON MYTABLE (COL2, COL3)
Теперь индекс находится в обоих вычисляемых столбцах COL2 и COL3, поэтому проблем нет:
ID COL1 COL2 COL3
1 [NULL] 1 1
2 1 1 0