¿Podría alguien explicar el siguiente comportamiento en SQL?
SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)
¿Podría alguien explicar el siguiente comportamiento en SQL?
SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)
Respuestas:
<>
es el estándar SQL-92; !=
es su equivalente Ambos evalúan los valores, lo que NULL
no es: NULL
es un marcador de posición para decir que existe la ausencia de un valor.
Es por eso que solo puede usar IS NULL
/ IS NOT NULL
como predicados para tales situaciones.
Este comportamiento no es específico de SQL Server. Todos los dialectos SQL que cumplen con los estándares funcionan de la misma manera.
Nota : para comparar si su valor no es nulo , use IS NOT NULL
, mientras que para comparar con un valor no nulo , use <> 'YOUR_VALUE'
. No puedo decir si mi valor es igual o no a NULL, pero puedo decir si mi valor es NULL o NOT NULL. Puedo comparar si mi valor es algo distinto de NULL.
!=
hasta ~ 9i, según tengo entendido, lo que trajo mucha sintaxis ANSI-92. Mi creencia es que MySQL es similar, comenzando el soporte en 4.x.
!=
podría haberse incluido en una especificación posterior como alternativa a <>
. No tengo en mis manos nuevas especificaciones, así que no puedo decir con certeza.
WHERE MyColumn != NULL
o WHERE MyColumn = NULL
determinista? O, en otras palabras, ¿se garantiza que siempre devuelva 0 filas, sin importar si MyColumn
es anulable en la base de datos o no?
!=
solo evalúa los valores, hacer algo como WHERE MyColumn != 'somevalue'
esto no devolverá los registros NULL.
NULL no tiene valor, por lo que no se puede comparar con los operadores de valor escalar.
En otras palabras, ningún valor puede ser igual (o no igual a) NULL porque NULL no tiene valor.
Por lo tanto, SQL tiene predicados especiales IS NULL y IS NOT NULL para tratar con NULL.
'a' != null
NO devolver un valor ( true
/ 1
) es contrario a la intuición y me atrapa de vez en cuando! Pensé que "algún valor comparado con ningún valor" siempre sería "no igual", pero tal vez solo soy yo.
SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'
asignar una constante si es un valor NULL, siempre que proporcione un tipo de datos apropiado para el valor centinela x (en este caso, una cadena / char). Esta es la sintaxis de TSQL, pero Oracle y otros motores tienen características similares.
Tenga en cuenta que este comportamiento es el comportamiento predeterminado (ANSI).
Si tu:
SET ANSI_NULLS OFF
http://msdn.microsoft.com/en-us/library/ms188048.aspx
Obtendrás resultados diferentes.
SET ANSI_NULLS OFF
aparentemente se irá en el futuro ...
create unique index UK_MyTable on MyTable (Column) where Column is not null
): msdn.microsoft.com/en-us/library/cc280372.aspx
SET ANSI_NULLS
está desactivado, los operadores de comparación Igual (=) y No igual a (<>) no siguen el estándar ISO. Una instrucción SELECT que utiliza WHERE column_name = NULL
devuelve las filas que tienen valores nulos en column_name. Una instrucción SELECT que utiliza WHERE column_name <> NULL
devuelve las filas que tienen valores no nulos en la columna. Además, una instrucción SELECT que usa WHERE column_name <> XYZ_value
devuelve todas las filas que no son XYZ_value y que no son NULL. En mi humilde opinión, esta última declaración parece un poco extraña en su exclusión de nulos de los resultados!
En SQL, todo lo que evalúa / calcula con NULL
resultados en DESCONOCIDO
Es por eso que SELECT * FROM MyTable WHERE MyColumn != NULL
o SELECT * FROM MyTable WHERE MyColumn <> NULL
te da 0 resultados.
Para proporcionar una comprobación de NULL
valores, se proporciona la función isNull.
Además, puede usar el IS
operador como lo hizo en la tercera consulta.
Espero que esto ayude.
La única prueba para NULL es IS NULL o IS NOT NULL. Las pruebas de igualdad no tienen sentido porque, por definición, uno no sabe cuál es el valor.
Aquí hay un artículo de Wikipedia para leer:
Usamos
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
para devolver todas las filas donde MyColumn es NULL o todas las filas donde MyColumn es una cadena vacía. Para muchos "usuarios finales", el problema de NULL frente a cadena vacía es una distinción sin necesidad ni punto de confusión.
Simplemente no veo la razón funcional y sin problemas para que los valores nulos no sean comparables con otros valores u otros valores nulos, porque podemos compararlo claramente y decir que son iguales o no en nuestro contexto. Es gracioso. Solo por algunas conclusiones lógicas y consistencia, necesitamos molestarnos constantemente con eso. No es funcional, hágalo más funcional y deje que los filósofos y los científicos concluyan si es consistente o no y si tiene "lógica universal". :) Alguien puede decir que es debido a índices o algo más, dudo que esas cosas no puedan hacerse para admitir valores nulos iguales. Es lo mismo que comparar dos vasos vacíos, uno es vidrio de vid y otro es vaso de cerveza, no estamos comparando los tipos de objetos sino los valores que contienen, lo mismo que se podría comparar int y varchar, con nulo ' s aún más fácil, no es nada y lo que dos nada tienen en común, son lo mismo, claramente comparables por mí y por todos los demás que escriben sql, porque constantemente estamos rompiendo esa lógica al compararlos de manera extraña debido a algunos estándares ANSI. ¿Por qué no utilizar la potencia de la computadora para hacerlo por nosotros? Dudo que esto desacelere las cosas si todo lo relacionado se construye teniendo esto en cuenta. "No es nulo, no es nada", no es manzana, es apfel, vamos ... Funcionalmente es tu amigo y también hay lógica aquí. Al final, lo único que importa es la funcionalidad y el uso de valores nulos de esa manera brinda más o menos funcionalidad y facilidad de uso. ¿Es más útil? porque constantemente estamos rompiendo esa lógica al compararlos de manera extraña debido a algunos estándares ANSI. ¿Por qué no utilizar la potencia de la computadora para hacerlo por nosotros? Dudo que esto desacelere las cosas si todo lo relacionado se construye teniendo esto en cuenta. "No es nulo, no es nada", no es manzana, es apfel, vamos ... Funcionalmente es tu amigo y también hay lógica aquí. Al final, lo único que importa es la funcionalidad y el uso de valores nulos de esa manera brinda más o menos funcionalidad y facilidad de uso. ¿Es más útil? porque constantemente estamos rompiendo esa lógica al compararlos de manera extraña debido a algunos estándares ANSI. ¿Por qué no utilizar la potencia de la computadora para hacerlo por nosotros? Dudo que esto desacelere las cosas si todo lo relacionado se construye teniendo esto en cuenta. "No es nulo, no es nada", no es manzana, es apfel, vamos ... Funcionalmente es tu amigo y también hay lógica aquí. Al final, lo único que importa es la funcionalidad y el uso de valores nulos de esa manera brinda más o menos funcionalidad y facilidad de uso. ¿Es más útil? s no apple es apfel, vamos ... Funcionalmente es tu amigo y también hay lógica aquí. Al final, lo único que importa es la funcionalidad y el uso de valores nulos de esa manera brinda más o menos funcionalidad y facilidad de uso. ¿Es más útil? s no apple es apfel, vamos ... Funcionalmente es tu amigo y también hay lógica aquí. Al final, lo único que importa es la funcionalidad y el uso de valores nulos de esa manera brinda más o menos funcionalidad y facilidad de uso. ¿Es más útil?
Considera este código:
SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end
¿Cuántos de ustedes saben qué devolverá este código? Con o sin NOT devuelve 0. Para mí eso no es funcional y es confuso. En c # todo es como debería ser, las operaciones de comparación devuelven valor, lógicamente esto también produce valor, porque si no fuera así, no hay nada que comparar (excepto. Nada :)). Simplemente "dijeron": cualquier cosa en comparación con nulo "devuelve" 0 y eso crea muchas soluciones y dolores de cabeza.
Este es el código que me trajo aquí:
where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)
Solo necesito comparar si dos campos (en donde) tienen valores diferentes, podría usar la función, pero ...
NULL No se puede comparar con ningún valor utilizando los operadores de comparación. NULL = NULL es falso. Nulo no es un valor. El operador IS está especialmente diseñado para manejar comparaciones NULL.
null = null
donde se podría usar 1=0
en alguna consulta ad-hoc. Y si se quejan, lo cambio a null != null
:)
Antigua pregunta, pero la siguiente podría ofrecer más detalles.
null
no representa ningún valor o un valor desconocido. No especifica por qué no hay valor, lo que puede generar cierta ambigüedad.
Supongamos que ejecuta una consulta como esta:
SELECT *
FROM orders
WHERE delivered=ordered;
es decir, está buscando filas donde las fechas ordered
y delivered
sean iguales.
¿Qué se puede esperar cuando una o ambas columnas son nulas?
Debido a que al menos una de las fechas es desconocida, no puede esperar decir que las 2 fechas son las mismas. Este también es el caso cuando ambas fechas son desconocidas: ¿cómo pueden ser las mismas si ni siquiera sabemos cuáles son?
Por esta razón, cualquier expresión que se trate null
como un valor debe fallar. En este caso, no coincidirá. Este también es el caso si intenta lo siguiente:
SELECT *
FROM orders
WHERE delivered<>ordered;
Nuevamente, ¿cómo podemos decir que dos valores no son iguales si no sabemos cuáles son?
SQL tiene una prueba específica para valores faltantes:
IS NULL
Específicamente, no está comparando valores, sino que busca valores perdidos .
Finalmente, en lo que respecta al !=
operador, que yo sepa, en realidad no está en ninguno de los estándares, pero es muy compatible. Se agregó para que los programadores de algunos idiomas se sientan más en casa. Francamente, si un programador tiene dificultades para recordar qué idioma está usando, tiene un mal comienzo.
NULL
queremos decir que estamos comparando un valor con 'tener un NULL
valor', no el valor con "el valor indeterminado que NULL
está teniendo la base", pero que no sabemos ", que obviamente no podremos saber nunca. Eso realmente facilitaría las cosas.
IS NULL
sea mucho más arduo que escribir = NULL
. Creo que sería más consistente si WHERE columnA = columnB
tuviera la misma interpretación que WHERE columnA = NULL
, en lugar de tratar a este último como un caso especial. Recuerda que noNULL
es un valor. En los lenguajes de programación donde es legítimo probarlo es porque tiene un significado diferente; no representa algo desconocido, sino un restablecimiento deliberado de un valor. No es así con SQL. variable == null
null
IS NULL
AND =NULL
en su último ejemplo. Pero eche un vistazo al último de Hover. Estoy cansado de experimentarlo una y otra vez, tener que hacer un montón de ¿innecesario? comprobación adicional ...
Me gustaría sugerir este código que hice para encontrar si hay un cambio en un valor,
i
siendo el nuevo valor y d
el antiguo (aunque el orden no importa). Para el caso, un cambio de valor a nulo o viceversa es un cambio, pero de nulo a nulo no lo es (por supuesto, de valor a otro valor es un cambio, pero de valor al mismo no lo es).
CREATE FUNCTION [dbo].[ufn_equal_with_nulls]
(
@i sql_variant,
@d sql_variant
)
RETURNS bit
AS
BEGIN
DECLARE @in bit = 0, @dn bit = 0
if @i is null set @in = 1
if @d is null set @dn = 1
if @in <> @dn
return 0
if @in = 1 and @dn = 1
return 1
if @in = 0 and @dn = 0 and @i = @d
return 1
return 0
END
Para usar esta función, puede
declare @tmp table (a int, b int)
insert into @tmp values
(1,1),
(1,2),
(1,null),
(null,1),
(null,null)
---- in select ----
select *, [dbo].[ufn_equal_with_nulls](a,b) as [=] from @tmp
---- where equal ----
select *,'equal' as [Predicate] from @tmp where [dbo].[ufn_equal_with_nulls](a,b) = 1
---- where not equal ----
select *,'not equal' as [Predicate] from @tmp where [dbo].[ufn_equal_with_nulls](a,b) = 0
Los resultados son:
---- in select ----
a b =
1 1 1
1 2 0
1 NULL 0
NULL 1 0
NULL NULL 1
---- where equal ----
1 1 equal
NULL NULL equal
---- where not equal ----
1 2 not equal
1 NULL not equal
NULL 1 not equal
El uso de sql_variant lo hace compatible para una variedad de tipos
NULL no es nada ... es desconocido. NULL no es igual a nada. Es por eso que debe usar la frase mágica IS NULL en lugar de = NULL en sus consultas SQL
Puede consultar esto: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx
<>
que está en la especificación 92, pero la mayoría de los proveedores admiten!=
y / o se incluye en una especificación posterior como 99 o 03.