Значение поля должно быть уникальным, если оно не равно NULL. Не равно null sql
Значение поля должно быть уникальным, если оно не равно NULL [sql-server-2005]
Вот альтернативный способ сделать это с ограничением. Чтобы обеспечить выполнение этого ограничения, вам понадобится функция, которая подсчитывает количество вхождений значения поля. В вашем ограничении просто убедитесь, что этот максимум равен 1.
Ограничение:
field is null or dbo.fn_count_maximum_of_field(field) < 2РЕДАКТИРОВАТЬ Я не могу вспомнить прямо сейчас - и не могу это проверить - проверяется ли проверка ограничений перед вставкой / обновлением или после. Я думаю, что после того, как вставка / обновление вернется к отказу. Если окажется, что я ошибаюсь, то 2 выше должно быть 1.
Функция таблицы возвращает int и использует следующий выбор для ее получения
declare @retVal int select @retVal = max(occurrences) from ( select field, count(*) as occurrences from dbo.tbl where field = @field group by field ) tmpЭто должно быть достаточно быстро, если ваша колонка как (не уникальный) индекс на нем.
Вы можете сделать это, создав вычисленный столбец и поместив уникальный индекс в этот столбец.
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)Это предполагает, что идентификатор - это ПК вашей таблицы, а COL1 - столбец «уникальный или нулевой».
Вычисленный столбец (COL2) будет использовать значение PK, если ваш «уникальный» столбец равен NULL.
По-прежнему существует вероятность столкновений между столбцом 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 2code-examples.net
Работа с NULL-значениями - IS NULL и IS NOT NULL
NULL-значение
Достаточно часто встречаются такие случаи, когда в таблице имеются записи с не заданными значениями какого-либо из полей, потому что значение поля неизвестно или его просто нет. В таких случаях SQL позволяет указать в поле NULL-значение. Строго говоря, NULL-значение вовсе не представлено в поле. Когда значение поля есть NULL — это значит, что программа базы данных специальным образом помечает поле, как не содержащее какого-либо значения для данной строки (записи). Дело обстоит не так в случае простого приписывания полю значения «нуль» или «пробел», которые база данных трактует как любое другое значение. Поскольку NULL не является значением как таковым, он не имеет типа данных. NULL может размещаться в поле любого типа. Тем не менее, NULL, как NULL-значение, часто используется в SQL.Предположим, появился покупатель, которому еще не назначен продавец. Чтобы констатировать этот факт, нужно ввести значение NULL в поле snum, а реальное значение включить туда позже, когда данному покупателю будет назначен продавец.
IS NULL
Поскольку NULL фиксирует пропущенные значения, результат любого сравнения при наличии NULL-значений неизвестен. Когда NULL-значение сравнивается с любым значением, даже с NULL-значением, результат просто неизвестен. Булево значение «неизвестно» ведет себя также, как «ложь» — строка, на которой предикат принимает значение «неизвестно», не включается в результат запроса – при одном важном исключении: NOT от лжи есть истина (NOT (false)=true), тогда как NOT от неизвестного значения есть также неизвестное значение. Следовательно, такое выражение как «city = NULL» или «city IN (NULL)» является неизвестным независимо от значения city.Часто необходимо различать false и unknown – строки, содержащие значения столбца, не удовлетворяющие предикату, и строки, которые содержат NULL. Для этой цели SQL располагает специальным оператором IS, который используется с ключевым словом NULL для локализации NULL-значения.
SQL IS NULL. Пример.Вывести все поля из талицы Customers, значения поля city которых равны NULL:
SELECT * FROM Customers WHERE city IS NULL
В данном случае выходных данных не будет, поскольку в поле city нет NULL-значений.
IS NOT NULL
Условие IS NOT NULL используется в запросах для выборки записей со значениями не равных значению NULLSQL IS NOT NULL. Пример.Вывести все поля из талицы Customers, значения поля city которых НЕ равны NULL:
SELECT * FROM Customers WHERE city IS NOT NULL
sql-language.ru
sql - показывая нуль, если значение sql равно NULL
Я не совсем уверен, что понимаю этот вопрос, но я думаю, что вы этого хотите:
select count(codes.lcfruh) as front_lcfruh, dienstplan.kw, dienstplan.datum from dienstplan left join codes on dienstplan.schicht = codes.lcfruh and codes.lcfruh <> '' left join personal on personal.perso_id = dienstplan.perso_id and personal.status = 'rezeption' and dienstplan.kw = $kw group by dienstplan.datum, dienstplan.kwЕсли schicht исходит из dienstplan, всегда будет строка для этого (так как это таблица вождения). Если я правильно вас понял, вы хотите, чтобы 0 если совпадающие строки не найдены. Поэтому вам нужно подсчитать объединенную таблицу.
Редактировать: Условие, в where codes.lcfruh != '' внешнее соединение обратно во внутреннее соединение, потому что любая "внешняя" строка будет иметь lcfruh как NULL, и любое сравнение с NULL дает "неизвестно", и поэтому строки удаляются из окончательного результата. Если вы хотите исключить строки в таблице codes где lcfruh имеет пустую строку, вам нужно переместить это условие в предложение JOIN (см. Выше).
И еще две вещи: привыкнуть к префиксным столбцам в запросе с более чем одной таблицей. Это позволяет избежать двусмысленности и делает запрос более устойчивым к изменениям. Вы также должны понимать разницу между литералами чисел и строковыми литералами 1 - это число '1' - это строка. Это плохая привычка использовать строковые литералы, где числа ожидаются. MySQL довольно прощает, поскольку он всегда пытается "как-то" работать, но если вы когда-либо пользовались другими СУБД, вы могли бы получить ошибки, которые не понимаете.
Кроме того, ваше использование group by неверно и приведет к возврату "случайных" значений. Пожалуйста, ознакомьтесь с этими сообщениями в блоге, чтобы понять, почему:
Каждая другая СУБД будет отклонять ваш запрос так, как он написан сейчас (и MySQL также будет, если вы включите более ANSI-совместимый режим)
null - Почему SQL не поддерживает "= null" вместо "null"?
Я не могу не чувствовать, что вы все еще не удовлетворены ответами, которые были даны до сих пор, поэтому я подумал, что попробую еще один курс. Дайте пример (нет, я не знаю, почему этот конкретный пример пришел мне в голову).
У нас есть таблица для сотрудников, EMP:
EMP --- EMPNO GIVENNAME E0001 Boris E0002 Chris E0003 Dave E0004 Steve E0005 TonyИ по какой-то причудливой причине мы отслеживаем, какие цветные штаны каждый сотрудник выбирает носить в определенный день (TROUS):
TROUS ----- EMPNO DATE COLOUR E0001 20110806 Brown E0002 20110806 Blue E0003 20110806 Black E0004 20110806 Brown E0005 20110806 Black E0001 20110807 Black E0003 20110807 Black E0004 20110807 GreyЯ мог бы продолжить. Мы пишем запрос, где мы хотим узнать имя каждого сотрудника и какие цветные штаны у них были 7 августа:
SELECT e.GIVENNAME,t.COLOUR FROM EMP e LEFT JOIN TROUS t ON e.EMPNO = t.EMPNO and t.DATE = '20110807'И получим набор результатов:
GIVENNAME COLOUR Chris NULL Steve Grey Dave Black Boris Black Tony NULLТеперь этот набор результатов может быть в представлении, или CTE, или что-то еще, и мы, возможно, захотим продолжить задавать вопросы об этих результатах, используя SQL. Какие могут быть некоторые из этих вопросов?
-
Были ли в тот день Дейва и Бориса в темных цветных штанах? (Да, черный == Черный)
-
Были ли Дэйв и Стив в тех же цветах в тот день? (Нет, Черный!= Серый)
-
Были ли в тот день Борис и Тони в одних и тех же цветных брюках? (Неизвестно - мы пытаемся сравнить с NULL, и мы следуем правилам SQL)
-
Были ли Борис и Тони не в тех же цветных штанах в этот день? (Неизвестно - мы снова сравниваем с NULL, и мы следуем правилам SQL)
-
Были ли в тот день Криса и Тони в тех же цветных брюках? (Неизвестно)
Обратите внимание, что вы уже знаете о конкретных механизмах (например, IS NULL), чтобы заставить нужные вам результаты, если вы разработали базу данных, чтобы никогда не использовать NULL в качестве маркера для отсутствия информации.
Но в SQL NULL получили две роли (по крайней мере) - чтобы отметить неприменимую информацию (возможно, у нас есть полная информация в базе данных, а Крис и Тони не появились на работу в тот день или не сделали этого "ношу брюки" ) и отметить недостающую информацию (в этот день появился Крис, у нас просто нет информации, записанной в базе данных в настоящее время)
Если вы используете NULL чисто как маркер неприменимой информации, я предполагаю, что вы избегаете таких конструкций, как внешние соединения.
Мне интересно, что вы добавили NaN в комментарии к другим ответам, не заметив, что NaN и (SQL) NULL имеют много общего. Самое большое различие между ними заключается в том, что NULL предназначен для использования по всей системе, независимо от того, какой тип данных задействован.
Самая большая проблема заключается в том, что вы решили, что NULL имеет одно значение во всех языках программирования, и вы, кажется, чувствуете, что SQL нарушил это значение. Фактически, нуль на разных языках часто имеет тонко разные значения. На некоторых языках это синоним 0. В других нет, поэтому сравнение 0==null преуспеет в одних и не удастся другим. Вы упомянули VB, но VB (при условии, что вы говорите, версии .NET) не имеет значения null. Он имеет Nothing, что опять-таки немного отличается (это эквивалентно в большинстве случаев конструкции С# default(T)).
Значение поля должно быть уникальным, если оно не равно NULL MS SQL Server
Я использую SQL Server 2005.
У меня есть поле, которое должно содержать либо уникальное значение, либо значение NULL. Я думаю, что я должен выполнять это с помощью CHECK CONSTRAINT или TRIGGER for INSERT, UPDATE .
Есть ли преимущество использования ограничения здесь по триггеру (или наоборот)? Как может выглядеть такое ограничение / триггер?
Или есть другой, более подходящий вариант, который я не рассматривал?
Вот альтернативный способ сделать это с ограничением. Чтобы обеспечить выполнение этого ограничения, вам понадобится функция, которая подсчитывает количество вхождений значения поля. В вашем ограничении просто убедитесь, что этот максимум равен 1.
Ограничение:
field is null or dbo.fn_count_maximum_of_field(field) < 2РЕДАКТИРОВАТЬ Я не могу вспомнить прямо сейчас – и не могу это проверить – проверяется ли проверка ограничений перед вставкой / обновлением или после. Я думаю, что после того, как вставка / обновление вернется к отказу. Если окажется, что я ошибаюсь, то 2 выше должно быть 1.
Функция таблицы возвращает int и использует следующий выбор для ее получения
declare @retVal int select @retVal = max(occurrences) from ( select field, count(*) as occurrences from dbo.tbl where field = @field group by field ) tmpЭто должно быть достаточно быстро, если ваша колонка как (не уникальный) индекс на нем.
Я создаю представление с индексом, который игнорирует нули через предложение where … т. Е. Если вы вставляете нуль в таблицу, представление не имеет значения, но если вы введете ненулевое значение, представление будет принудительно использовать ограничение.
create view dbo.UniqueAssetTag with schemabinding as select asset_tag from dbo.equipment where asset_tag is not null GO create unique clustered index ix_UniqueAssetTag on UniqueAssetTag(asset_tag) GOИтак, теперь моя таблица оборудования имеет столбец asset_tag, который допускает множество нулей, но только уникальные ненулевые значения.
Примечание. Если вы используете mssql 2000, вам нужно « SET ARITHABORT ON » прямо перед тем, как любая вставка, обновление или удаление будет выполнена в таблице. Довольно точно, что это не требуется на mssql 2005 и выше.
Вы можете сделать это, создав вычисленный столбец и поместив уникальный индекс в этот столбец.
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)Это предполагает, что идентификатор – это ПК вашей таблицы, а COL1 – столбец «уникальный или нулевой».
Вычисленный столбец (COL2) будет использовать значение PK, если ваш «уникальный» столбец равен NULL.
По-прежнему существует вероятность столкновений между столбцом 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В Oracle уникальный ключ позволит использовать несколько NULL.
В SQL Server 2005 хороший подход заключается в том, чтобы делать ваши вставки через представление и отключать прямые вставки в таблицу.
Вот пример кода.
Есть ли первичный ключ в этой таблице, может быть, столбец Identity? Вы можете создать уникальный ключ, который является составной частью поля, в котором вы выполняете уникальность в сочетании с первичным ключом.
Здесь обсуждается только такой вопрос: http://blog.sqlauthority.com/2008/09/07/sql-server-explanation-about-usage-of-unique-index-and-unique-constraint/
FYI – SQL Server 2008 вводит отфильтрованные индексы, которые позволят вам подойти к этому немного по-другому.
Обычно триггер позволит вам предоставить более подробное и пояснительное сообщение, чем контрольное ограничение, поэтому я использовал их, чтобы избежать «плохой» игры в отладке.
Ограничение намного легче, чем триггер, хотя уникальное ограничение является фактически индексом.
Однако вам разрешен только один NULL в уникальном ограничении / индексе. Таким образом, вам придется использовать триггер для обнаружения дубликатов.
Запрошено из MS игнорировать NULLS , но SQL 2008 имеет отфильтрованные индексы (как упоминалось, когда я печатаю это)
sqlserver.bilee.com