Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
 Re: Как написать "не равны" для nullable поля?  [new]
andrey odegov
Member

Откуда:
Сообщений: 473
alexeyvg
invm
NULL не подходит.
Непонятно, почему?
Вот как раз если вам нужен маркер "нет данных", то это как раз он и есть.
Наверное сложно понять, что заложено в null: "нет данных", "данные не известны" или "данные не применимы".
17 авг 12, 19:33    [13028763]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
мимо
Mnior
Но при поиске использовать частично "понятийное" сравнение.
Это как?
Очень просто, поиск по похожести ровно что у ТС. Где NULL = NULL не в смысле математического равенства, а логического - данные " отсутствуют"/"не определены" или имеют значение согласно заданному (в переменной) критерию.
Ничего более.

мимо
При определенных обстоятельствах +100500 миллионов = бесконечность, что в свою очередь, можно описать как неопределённость и приравнять к null (данных так много, что можно сказать, что их нет)?
Ничего не понял.
Если вам надо одновременно в одном поле такие понятия:
- Конкретное значение
- Отсутствует значение
- Значение не определено (не может быть определено)
- +/- бесконечность
- мнимое значение
То на простых данных это невозможно в принципе.
Вам нужно или свой тип изобретать или вводить дополнительное поле.

andrey odegov
Наверное сложно понять, что заложено в null: "нет данных", "данные не известны" или "данные не применимы".
Лять, в том-то и дело, ничего в NULL не заложено. Каждый в праве сам решать что под этим подразумевать, когда проектирует систему.
Кто-то хочет заложить в NULL "нет данных", кто-то "бесконечность", а кто-то ещё что-то. Вот я заложил, что 1-добавление, 2-удаление,3-редактирование, а у вас по другому и NULL по другому. Конечно это надо документировать.
И естественно, что есть стандарты "понятия", но это лишь стандарты и рекомендации.
И это совершенно не важно.

NULL cуществовал, существует и будет существовать. И скорее не будет никакого расширения, типа EMPTY и ничего подобного Applicable/Inapplicable.
Дело в другом - в синтаксическом сахаре и оптимизаторе. Что-то он уже умеет на этих длинных формулах, но не всегда.
Иногда бывает нужна логика в определённых запросах, когда NULL это словно дополнительное значение и NULL == NULL.
И писать сложные выражения сложно и не эффективно.
Mnior
Т.к. мы уже имеем NULL (как одно понятие) то возможно только две группы операторов.
Нет, не верно.
Их больше, ещё может быть оператор который вернёт TRUE если с одной/любой стороны NULL.
Другое дело - а нужен ли он.

invm
Не важно как это значение будет храниться, важно, чтобы интерпретировалось оно везде одинаково
Это нереально и не нужно.
Проблема тут не в "интерпретировалось", а "что необходимо".
Допустим чётко определено понятие "нет данных". И для варианта "нет данных" <-> "нет данных" в одном случае надо что бы было TRUE, а в другом UNKNOWN, а в третьем ещё что-то. Где <-> может быть как "найди мне по указанному признаку", "равны" или ещё что-то типа "сопоставимы".

invm
, а то NULL в предикатах трактуется как UNKNOWN, а в операциях UNION, DISTINCT, GROUP BY, ORDER BY и т.п., -- как EMPTY.
А в CONSTRAINT вообще по другому.
И такое поведение
1. логично (разве что кроме CONSTRAINT)
2. проще для реализации любой необходимой логики
Комбинацией =/!=, IS и OR/AND можно что угодно сотворить. А для DISTINCT и т.п чтобы избежать схлопывания (смешивания, выравнивания) - хватает добавить ещё одну "разделяемою" колонку.
Это необходимый базис поведения (полнота, en).
18 авг 12, 04:06    [13029992]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
мимо
Guest
Mnior
ничего в NULL не заложено. Каждый в праве сам решать что под этим подразумевать, когда проектирует систему.


Вообще-то заложенно. В электротехнике есть такое понятие как состояние "высокого импенданса", т.е. когда на шине низкий потенциал это 0 (<0.8) , высокий - 1 (>2.4), если сигнала нет (но он есть: потенциал ~ 1.4), то "высокий импенданс". Null - это и моделирует(в него это заложенно). Как значение переменной, которая объявлена, но не проинициализированна.

А насчет подразумевать, тут никто не запрещает: девчонки в бухгалтерии подразумевают, что если сумма платежа "-1", то это отсутсвие платежа.
18 авг 12, 08:55    [13030110]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31868
andrey odegov
alexeyvg
пропущено...
Непонятно, почему?
Вот как раз если вам нужен маркер "нет данных", то это как раз он и есть.
Наверное сложно понять, что заложено в null: "нет данных", "данные не известны" или "данные не применимы".
ИМХО "нет данных" и "данные не известны" - это синонимы.

"данные не применимы" - это следствие того, что данных нет. То есть в принципе можно сделать так, что бы в поле можно было хранить конкретное значение, но пометить его флагом "данные не применимы", но практического смысла в таком хранении нет.

В принципе да, можно для каких вариантов сделать специальные значения (признаки), но по моему это слишком надуманно - большинство разработчиков с NULL не могут разобраться, а если ввести ещё несколько специальных значений, да и непонятно, как собственно всё это применять!

А вот насчёт специальных операторов я согласен с Mnior. Я вообще не понимаю, почему сделана такая логика, как сейчас, но это менять уже поздно, совместимость требует, а вот специальные операторы иметь было бы неплохо.
18 авг 12, 10:59    [13030196]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
andrey odegov
Member

Откуда:
Сообщений: 473
на весах с точностью 1 кг, что записать для тела, массой 50 гр? нет данных или неизвестно.
а если диапазон измерения этих весов от 10 кг до тонны, а тело массой 1.5 тонны - неизвестно,
неприменимо, или нельзя измерить? если нужно знать причину отсутствия данных, то одного
null мало.
18 авг 12, 14:10    [13030632]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31868
andrey odegov
на весах с точностью 1 кг, что записать для тела, массой 50 гр? нет данных или неизвестно.
а если диапазон измерения этих весов от 10 кг до тонны, а тело массой 1.5 тонны - неизвестно,
неприменимо, или нельзя измерить?
Для этих двух случаев массу нужно записать "неизвестно", поскольку она действительно неизвестна. Я вообще не понял, какая разница-то - в обоих случаях предмет не клали на весы ввиду того, что их нет (с нужными характеристиками). Или клали, а весы не показали достоверного результата.
18 авг 12, 19:14    [13031217]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
andrey odegov
Member

Откуда:
Сообщений: 473
причина неизвестности разная - в первом случае груба точность, в другом - мал диапазон.
18 авг 12, 22:22    [13031911]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31868
andrey odegov
причина неизвестности разная - в первом случае груба точность, в другом - мал диапазон.
Ага, согласен, но с полем то что не так, для этих 2-х причин микрософту нужно делать 2 специальных значения в сиквле?
А ещё значения для невнимательности кладовщика, для ошибок отдела закупок весов...

Я до сих пор не понимаю вашу мысль. По моему, очевидно, что к NULL значениям и к специальным операторам вышеперечисленное не имеет отношения.
18 авг 12, 22:45    [13031987]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31868
andrey odegov
если нужно знать причину отсутствия данных, то одного
null мало.
Собственно, если нужно знать причину отсутствия данных, то нужно делать справочник причин отсутствия, это же единственный вариант. Не нужно смешивать специальное значение для поля, обозначающее отсутствие данных, и описание причины этого отсутствия.
18 авг 12, 22:48    [13031998]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
andrey odegov
Member

Откуда:
Сообщений: 473
считать два null-значения неравными если причина установки в null была одна и та же?
переносить неизвестность сравниваемых null-значений на результат их сравнения?
19 авг 12, 16:01    [13033350]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31868
andrey odegov
считать два null-значения неравными если причина установки в null была одна и та же?
переносить неизвестность сравниваемых null-значений на результат их сравнения?
Я думаю, нужно считать два null-значения равными.

Несмотря на всё теоритизирование по этому поводу, я не знаю ни одной системы, в которой логика была бы устроена по другому (понятно, что такие всё таки есть, просто я не встречал).
19 авг 12, 21:25    [13034142]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
мимо
если сигнала нет (но он есть: потенциал ~ 1.4), то "высокий импенданс"
Null - это и моделирует(в него это заложенно).
Изначально NULL введён Коддом для OUTER JOIN.
И никакие импедансы в NULL не заложены. И я же цитировал выше, что тем же Коддом вводятся два понятия NULL (I-NULL и A-NULL, для OUTER JOIN и отсутствия данных в колонке).
мимо
Как значение переменной, которая объявлена, но не проинициализированна.
Вот давайте вы не будете сюда вводить императивщину, а заодно всякие аналогии и "доказательсва" на частностях.

Ok, alexeyvg +1. Но что скажут другие участники с "предлложением" (invm, iap ... )?
aleks2, как я понимаю - крайний консерватор. =)

И какие операторы вводить? Только одну группу (где NULL == NULL) или NULL == <Any> тоже?

Для операторов сопоставления ("равно" и "не равно") ещё понятно, а что с неравенствами ("больше"/"меньше") и другими операторами (IN, ALL, ANY, LIKE)?
Главное аккуратно, чтоб не вскрыть ящик Пандоры и не трогать мутаторы (+ - * / ...).
Лучше не трогать "словесные" операторы, но:
С ALL/ANY всё понятно - там предшествуют обычные операторы, но с LIKE, IN, BETWEEN могут быть споры.
- LIKE не заменяется, а кто-то будет ныть: хачу TRUE в Col LIKE @Var при Col и @Var == NULL.
- IN удобнее, мол не хочу 100500 элементов разворачивать в OR-ы

Да, уже есть операторы сортировки, но не всё так гладко с "больше"/"меньше".
Тоже вроде можно сказать фтопку, но опять таки найдутся апологеты:
Но там больше проблемы, ибо некоторые используют NULL как признак "без начала"/"без конца", в зависимости от колонки.
Тут только посоветовать заюзать костыль Min_Value / Max_Value для используемого типа.
Но проблема ещё остаётся с использованием = и ! в неравествах <= и >= (!< и !>).


И какие наборы символов использовать? А то некоторые пишут "<>" , а другие "!=". Типа "><" и "=!" Мне кажется не особо заметно.
Может просто добавления спец символа к имеющимся операторам, типа "#"


PS: Ссори, что оставляю вопрос сырым. Может чуть позже.
20 авг 12, 03:03    [13034841]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
мимо
Guest
Mnior
мимо
если сигнала нет (но он есть: потенциал ~ 1.4), то "высокий импенданс"
Null - это и моделирует(в него это заложенно).
Изначально NULL введён Коддом для OUTER JOIN.
И никакие импедансы в NULL не заложены. И я же цитировал выше, что тем же Коддом вводятся два понятия NULL (I-NULL и A-NULL, для OUTER JOIN и отсутствия данных в колонке).

Угу, и мир сотворил в 1970 г... Ясный фиг, что ежели из двух таблиц делать одну, то разряженность(отсутствие данных) надо было чем-то заполнять. Поэтому, логично было взять уже имеющиеся понятие и широко используемое для таких целей от электротехники до языков программирования.

Mnior
мимо
Как значение переменной, которая объявлена, но не проинициализированна.
Вот давайте вы не будете сюда вводить императивщину, а заодно всякие аналогии и "доказательсва" на частностях.

И предложите ещё считать суть разными и не связанными понятия: "реляционная алгебра" и "реляционное счисление" и не имеющим никакого отношения к sql.
20 авг 12, 11:11    [13035596]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
NIIIK
Member

Откуда: Россия, Ростовская область, г. Таганрог
Сообщений: 1295
В основном поддерживаю логику Mnior

Но моё мнение, что часто если понадобилось делать такое сравнение (не всегда), то это ошибка проектирования.

иногда надо делать значение "не установлено" и т. п., а так же "переделывать в обязательный со значением (частенько со значением по умолчанию).

Например, делаем атрибут "пол" у "человек" - делаем его обязательным, но при этом имеем данные не для всех людей "нет данных - тоже данные и устанавливаем значение".

Для единичных запросов (обновления, импорта, фикса и т. п.) можно и OR обойтись. Для "важных и частых запросов" лучше сделать так, что бы "не надо было писать OR-оператор" (или подзапрос с not exists (intersect)).
20 авг 12, 12:27    [13036093]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
MyNiGoo
Member

Откуда:
Сообщений: 233
я считаю, что нефиг плодить новые сущности. Еще голову ломать, Null - данные не определены, Empty - данных нет, Smth1 - пятка зачесалась, так можно бесконечно. Есть Null и отлично, замечательно отражает реальность.
21 авг 12, 15:52    [13044115]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Mnior
PS: Ссори, что оставляю вопрос сырым. Может чуть позже.
Нужно ещё раз чётко определить задачи решающие новыми операторами.

Поиск по критерию, где в параметрах критерия может быть:
1. <Данные не определены>, т.е. искать где данные не определены
2. <Критерий не определён> - т.е. выражение должно игнорироваться

Последний пункт решается всегда так:
AND ([Column] = @Param OR @Param IS NULL)
Но вроде как разрулить его эффективно без отдельного UNION невозможно. И это очень сильно портит все планы, ибо даже если добавить новый оператор, он не всегда поможет упростить (без ReCompile).
Если итак кто-то согласен на ReCompile, то тогда максимум что стоит просить, чтобы банальное выражение упрощалась:
DECLARE	@Test TABLE (
	 ID	Int	IDENTITY
	 PRIMARY KEY
	,Price	Money NULL
	,UNIQUE (Price,ID)
)INSERT	@Test (Price) VALUES (NULL),(1),(2)
DECLARE	 @Price1 Money = NULL
	,@Price2 Money = 1

SELECT * FROM @Test WHERE Price = @Price1 OR Price IS NULL AND @Price1 IS NULL OPTION(ReCompile)
SELECT * FROM @Test WHERE Price = @Price2 OR Price IS NULL AND @Price2 IS NULL OPTION(ReCompile)
SELECT * FROM @Test WHERE Price = @Price1 OR Price IS NULL AND @Price1 IS NULL

SELECT * FROM @Test WHERE Price != @Price1 OR Price IS NULL AND @Price1 IS NOT NULL OR Price IS NOT NULL AND @Price1 IS NULL OPTION(ReCompile)
SELECT * FROM @Test WHERE Price != @Price2 OR Price IS NULL AND @Price2 IS NOT NULL OR Price IS NOT NULL AND @Price2 IS NULL OPTION(ReCompile)
SELECT * FROM @Test WHERE Price != @Price1 OR Price IS NULL AND @Price1 IS NOT NULL OR Price IS NOT NULL AND @Price1 IS NULL
Seek Keys[1]: Prefix: Price = Scalar Operator(NULL)
Seek Keys[1]: Prefix: Price = Scalar Operator(($1.0000))
Seek Keys[1]: Prefix: Price = Scalar Operator([@Price1])

Seek Keys[1]: IsNotNull: Price
Scan Predicate: [Price] IS NULL OR [Price]<>($1.0000)
Scan Predicate: [Price]<>[@Price1] OR [@Price1] IS NOT NULL AND [Price] IS NULL OR [@Price1] IS NULL AND [Price] IS NOT NULL

Full Scan
Seek Keys[1]: Prefix: Price = Scalar Operator(($1.0000))
Scan Predicate: [Price]=[@Price1] OR [@Price1] IS NULL
Что так и делается (иногда даже и без ReCompile !!!).

Следовательно, ничего кроме банального синтаксического сахара новый оператор не даёт (вроде как), что не будет большим стимулом для M$ и сообщества.
Данную консрукцию (#<>), как у TC я ранее не встречал, ценность оного оператора малая.
Другие реальные задачи для оператора не вижу.

Синтаксис. По аналогии IS NULL можно ввести оператор EQUAL:
WHERE [Column]     EQUAL @Param
WHERE [Column] NOT EQUAL @Param
21 авг 12, 18:54    [13045449]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Забыл последнюю группу запросов:
SELECT * FROM @Test WHERE Price = @Price1 OR @Price1 IS NULL OPTION(ReCompile)
SELECT * FROM @Test WHERE Price = @Price2 OR @Price2 IS NULL OPTION(ReCompile)
SELECT * FROM @Test WHERE Price = @Price1 OR @Price1 IS NULL
21 авг 12, 18:55    [13045456]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
Cobalt747
Member

Откуда:
Сообщений: 2308
Kudep
Как одной строкой написать следующий предикат:
price is null and @price is not null
	or price is not null and @price is null
	or price <> @price

Смысл предиката проверить, что price не равен @price. Оба значения могут содержать null.

price xor @price

?
22 авг 12, 09:31    [13047077]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Ставим плюсики.
EQUAL operator

Сообщаем ошибки. Обсуждаем проблемы, помарки недочёты.
29 авг 12, 09:21    [13079759]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Mnior
EQUAL operator

Как видим, уже были заявления:
Operator for Nullable Column Comparison (+35)
Add language and optimizer support for ISO <distinct predicate> (+181)
29 авг 12, 09:26    [13079779]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
iap
Member

Откуда: Москва
Сообщений: 47085
Mnior
Mnior
EQUAL operator

Как видим, уже были заявления:
Operator for Nullable Column Comparison (+35)
Add language and optimizer support for ISO <distinct predicate> (+181)
Причём, заявлено аж 5 лет назад!
Хоть и ISO стандарт.
Уже в трёх версиях могли бы реализовать. Пофигисты!
29 авг 12, 09:38    [13079859]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
iap
NOT EXISTS(SELECT price INTERSECT SELECT @price)
В Workarounds того поста висит это:
Undocumented Query Plans: Equality Comparisons от Paul White
Вот такая форма записи типа считается приемлемой, для них видимо, вот и не рыпаются.

Мне кажется даже только если увеличить головос эдак в 2 раза, тогда просто будет тяжело выкручиваться. А до этого ничего не изменится.

Есть ещё один способ - надо показать что этот EXISTS INTERSECT не сработает в каком нидь более тяжёлом запросе и они не признают, что им же лучше для упрощения оптимизатора.
И тут две проблемы, мало кто так умеет писать, мало кто из умеющих будет выёживаться, а перепишет весь запрос или ещё как.
Короче, надо не ленится в своих повседневных зададах наезжать на MS, а не делать из себя крутого перца по переписыванию запросов.
29 авг 12, 10:03    [13080020]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
iap
Member

Откуда: Москва
Сообщений: 47085
Mnior,

а где это я делал из себя "крутого перца по переписыванию запросов"?
29 авг 12, 10:06    [13080048]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
iap
а где это я делал из себя "крутого перца по переписыванию запросов"?
Упс. Это не личный наезд (не могу понять что как вы так подумали). Это даже не наезд, а проблема нашего сообщества. Проблема взаимодействия.
29 авг 12, 10:12    [13080081]     Ответить | Цитировать Сообщить модератору
 Re: Как написать "не равны" для nullable поля?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Проблема втом что мы плохо понимаем сами, полохо говорим, делаем не то и нас не хотят внимательно слушать.
Когда теория хорошо сходится с практикой - всё зашибись, но когда нет, то "адепты" начинают каприхзничать "все тупицы, так делать нельзя"
Как сказал один - программирование это не наука, программирование это социология/психология.

Согласен, что я больше свой опыт накладываю, но иногда надо вспомнить, что приходится неистово выёпываться чтобы запустить запрос оптимально, со всеми индексами. И мы на форумах советуем переписвать запросы, через UNION через ещё абы как, хотя мы и только мы должны понять проблему глубже и вместо того чтобы защищать MS от "набегов хомячков" надо "давить наверх" что они там бездельничают, правильно формализовав проблему.
29 авг 12, 10:29    [13080199]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить