funciones - Por qué NULL=NULL se evalúa como falso en el servidor SQL
funciones escalares sql (14)
En el servidor SQL si tiene nullParam=NULL
en una cláusula where, siempre se evalúa como falso. Esto es contrario a la intuición y me ha causado muchos errores. Entiendo que las palabras clave IS NULL
e IS NOT NULL
son la forma correcta de hacerlo. Pero, ¿por qué el servidor SQL se comporta de esta manera?
¿Qué edad tiene Frank? No lo sé (nulo).
¿Qué edad tiene Shirley? No lo sé (nulo).
¿Frank y Shirley tienen la misma edad?
La respuesta correcta debería ser "No sé" (nulo), no "no", ya que Frank y Shirley podrían tener la misma edad, simplemente no lo sabemos.
Aquí espero aclarar mi posición.
Que NULL = NULL
evalúe a FALSE
es incorrecto. Hacker y Mister respondieron correctamente NULL
. Aquí está el por qué. Dewayne Christensen me escribió, en un comentario a Scott Ivey :
Como es diciembre, usemos un ejemplo estacional. Tengo dos regalos debajo del árbol. Ahora, dime si obtuve dos de lo mismo o no.
Pueden ser diferentes o pueden ser iguales, no lo sabes hasta que abres ambos regalos. ¿Quién sabe? Invitaste a dos personas que no se conocen y ambos te han hecho el mismo regalo: raro, pero no imposible § .
Entonces la pregunta: ¿estos dos DESCONOCIDOS presentan lo mismo (igual, =)? La respuesta correcta es: DESCONOCIDO (es decir, NULL
).
Este ejemplo pretendía demostrar que "... ( false
o null
, según su sistema) ..." es una respuesta correcta, no lo es, solo NULL
es correcto en 3VL (o está bien que acepte un sistema que da ¿respuestas incorrectas?)
Una respuesta correcta a esta pregunta debe enfatizar estos dos puntos:
- la lógica de tres valores (3VL) no es intuitiva (vea innumerables otras preguntas sobre este tema en y en otro foro para asegurarse);
- Los DBMS basados en SQL a menudo no respetan incluso 3VL, a veces dan respuestas incorrectas (como lo hace el cartel original, SQL Server en este caso).
Así que reitero: SQL no hace ningún bien forzando a uno a interpretar la propiedad reflexiva de igualdad, que declara que:
for any x, x = x
§§ (en inglés simple: cualquiera que sea el universo del discurso, una "cosa" siempre es igual a sí misma ).
.. en un 3VL ( TRUE
, FALSE
, NULL
). La expectativa de las personas se ajustará a 2VL ( TRUE
, FALSE
, que incluso en SQL es válido para todos los demás valores), es decir, x = x
siempre evalúa como TRUE
, para cualquier valor posible de x, sin excepciones.
Nótese también que los NULL son " valores no válidos" válidos (como sus apologistas pretenden que son) que se pueden asignar como valores de atributo (??) como parte de las variables de relación. Entonces son valores aceptables de todo tipo (dominio), no solo del tipo de expresiones lógicas.
Y este era mi punto : NULL
, como valor, es una "bestia extraña". Sin eufemismo, prefiero decir: tonterías .
Creo que esta formulación es mucho más clara y menos discutible, lo siento por mi falta de dominio del inglés.
Este es solo uno de los problemas de NULLs. Es mejor evitarlos por completo, cuando sea posible.
§ aquí nos preocupan los valores , por lo que el hecho de que los dos presentes sean siempre dos objetos físicos diferentes no es una objeción válida; si no está convencido de que lo siento, este no es el lugar para explicar la diferencia entre el valor y la semántica de "objetos" (el álgebra relacional tiene una semántica de valores desde el principio; véase el principio de información de Codd; creo que algunos implementadores de SQL DBMS incluso me importa una semántica común).
Según mi conocimiento, este es un axioma aceptado (en una forma u otra, pero siempre interpretado en un 2VL) desde la antigüedad y eso exactamente porque es muy intuitivo. 3VLs (es una familia de lógicas en realidad) es un desarrollo mucho más reciente (pero no estoy seguro de cuándo se desarrolló por primera vez).
Nota al margen: si alguien introduce Bottom , Unit y Option Types como intentos para justificar SQL NULL, estaré convencido solo después de un examen bastante detallado que mostrará cómo las implementaciones SQL con NULL tienen un sistema de tipo de sonido y aclarará, finalmente, qué NULLs (estos "valores-no-absolutamente-valores") realmente son.
En lo que sigue voy a citar algunos autores. Cualquier error u omisión probablemente sea mía y no de los autores originales.
Joe Celko en SQL NULLs
Veo a Joe Celko a menudo citado en este foro. Aparentemente es un autor muy respetado aquí. Entonces, me dije a mí mismo: "¿qué escribe sobre SQL NULLs? ¿Cómo explica los numerosos problemas de NULL?". Uno de mis amigos tiene una versión para libros electrónicos de SQL para smarties de Joe Celko: programación avanzada de SQL, 3ra edición . Veamos.
Primero, la tabla de contenidos. Lo que más me impresiona es el número de veces que se menciona a NULL y en los contextos más variados:
3.4 Aritmética y NULLs 109
3.5 Conversión de valores hacia y desde NULL 110
3.5.1 NULLIF () Función 110
6 NULLs: datos faltantes en SQL 185
6.4 Comparación de NULLs 190
6.5 NULLs y Logic 190
6.5.1 NULLS en predicados de subconsulta 191
6.5.2 Soluciones SQL estándar 193
6.6 Matemáticas y NULLs 193
6.7 Funciones y NULLs 193
6.8 NULLs e idiomas de host 194
6.9 Consejos de diseño para NULLs 195
6.9.1 Evitar valores NULL de los programas host 197
6.10 Una nota sobre múltiples valores nulos 198
10.1 IS NULL Predicado 241
10.1.1 Fuentes de NULLs 242
...
y así. Me suena a "desagradable caso especial".
Iré a algunos de estos casos con extractos de este libro, tratando de limitarme a lo esencial, por razones de derechos de autor. Creo que estas citas caen dentro de la doctrina del "uso justo" e incluso pueden estimular la compra del libro, así que espero que nadie se queje (de lo contrario, tendré que eliminar la mayor parte, si no todos). Además, me abstendré de informar fragmentos de código por la misma razón. Lo siento por eso. Compre el libro para leer sobre el razonamiento datailed.
Los números de página entre paréntesis en lo que sigue.
Restricción NOT NULL (11)
La restricción de columna más importante es NOT NULL, que prohíbe el uso de valores NULL en una columna. Use esta restricción de forma rutinaria y elimínela solo cuando tenga una buena razón. Le ayudará a evitar las complicaciones de los valores NULL cuando realiza consultas contra los datos.
No es un valor ; es un marcador que contiene un lugar donde podría ir un valor.
De nuevo, esta tontería de "valor pero no del todo un valor". El resto me parece bastante sensato.
(12)
En resumen, los NULL causan muchas características irregulares en SQL, que discutiremos más adelante. Su mejor opción es memorizar las situaciones y las reglas para NULL cuando no puede evitarlas.
A propósito de SQL, NULL e infinito:
(104) CAPÍTULO 3: DATOS NUMÉRICOS EN SQL
SQL no ha aceptado el modelo IEEE para las matemáticas por varias razones.
...
Si las reglas de IEEE para matemáticas se permitieran en SQL, entonces necesitaríamos reglas de conversión de tipo para infinito y una manera de representar un valor numérico exacto infinito después de la conversión. La gente tiene suficientes problemas con NULLs, así que no vayamos allí.
Implementaciones SQL indecisas sobre lo que NULL realmente significa en contextos particulares:
3.6.2 Funciones exponenciales (116)
El problema es que los logaritmos no están definidos cuando (x <= 0). Algunas implementaciones de SQL devuelven un mensaje de error, algunas devuelven un NULL y DB2 / 400; la versión 3 versión 1 devolvió * NEGINF (abreviatura de "infinito negativo") como resultado.
Joe Celko citando a David McGoveran y CJ Date:
6 NULLs: datos faltantes en SQL (185)
En su libro Una guía para Sybase y SQL Server , David McGoveran y CJ Date dijeron: "Es la opinión de este escritor que los NULL, al menos como se definen e implementan actualmente en SQL, son mucho más problemas de lo que valen y deben evitarse; Muestran un comportamiento muy extraño e incoherente y puede ser una rica fuente de error y confusión. (Tenga en cuenta que estos comentarios y críticas se aplican a cualquier sistema que admita NULL de estilo SQL, no solo a SQL Server específicamente).
NULLs como adicción a las drogas :
(186/187)
En el resto de este libro, te exhortaré a no usarlos , lo que puede parecer contradictorio, pero no lo es. Piensa en un NULO como droga; úsalo correctamente y funciona para ti, pero abusa de él y puede arruinar todo. Su mejor política es evitar NULL cuando pueda y usarlos adecuadamente cuando sea necesario.
Mi única objeción aquí es "usarlos adecuadamente", que interactúa mal con comportamientos de implementación específicos.
6.5.1 NULLS en Predicados de subconsulta (191/192)
La gente olvida que una subconsulta a menudo oculta una comparación con un NULL. Considera estas dos tablas:
...
El resultado estará vacío. Esto es contrario a la intuición , pero correcto.
(separador)
6.5.2 Soluciones SQL estándar (193)
SQL-92 resolvió algunos de los problemas de 3VL (lógica de tres valores) al agregar un nuevo predicado de la forma:
<condición de búsqueda> IS [NOT] TRUE | FALSO | DESCONOCIDO
Pero UNKNOWN es una fuente de problemas en sí misma, por lo que CJ Date, en su libro citado a continuación, recomienda en el capítulo 4.5. Evitar Nulos en SQL :
- No use la palabra clave UNKNOWN en ningún contexto.
Lea "ASIDE" en UNKNOWN, también vinculado a continuación.
6.8 NULLs e idiomas de host (194)
Sin embargo, debe saber cómo se manejan los NULL cuando deben pasarse a un programa host. Ningún lenguaje de host estándar para el que se define una incrustación admite NULL, que es otra buena razón para evitar su uso en el esquema de la base de datos.
(separador)
6.9 Consejos de diseño para NULLs (195)
Es una buena idea declarar todas las tablas base con restricciones NOT NULL en todas las columnas siempre que sea posible. Los NULL confunden a las personas que no conocen SQL y los NULL son caros.
Objeción: NULLs confunde incluso a las personas que conocen bien SQL, ver a continuación.
(195)
Los NULL deben evitarse en FOREIGN KEYs. SQL permite esta relación de "beneficio de la duda", pero puede causar una pérdida de información en consultas que involucran uniones. Por ejemplo, dado un código de número de pieza en Inventario al que se hace referencia como LLAVE EXTRAÑA por una tabla de Órdenes, tendrá problemas para obtener una lista de las partes que tienen un NULO. Esta es una relación obligatoria; no puedes pedir una parte que no existe.
(separador)
6.9.1 Evitar valores NULL de los programas host (197)
Puede evitar poner NULLs en la base de datos desde los Programas Host con alguna disciplina de programación.
...
- Determine el impacto de los datos faltantes en la programación y generación de informes: las columnas numéricas con NULL son un problema, ya que las consultas que usan funciones agregadas pueden proporcionar resultados engañosos.
(separador)
(227)
La SUMA () de un conjunto vacío siempre es NULL. Uno de los errores de programación más comunes al usar este truco es escribir una consulta que podría devolver más de una fila. Si no lo pensó, podría haber escrito el último ejemplo como: ...
(separador)
10.1.1 Fuentes de NULL (242)
Es importante recordar dónde pueden ocurrir NULLs. Son más que solo un posible valor en una columna . Las funciones agregadas en conjuntos vacíos, UNIONES ÚNICAS, expresiones aritméticas con NULLs y operadores OLAP devuelven valores NULL. Estos constructos a menudo aparecen como columnas en VIEWs.
(separador)
(301)
Otro problema con NULL se encuentra cuando intenta convertir predicados IN a predicados EXISTS.
(separador)
16.3 Todas las funciones Predicado y Extrema (313)
Es contra intuitivo al principio que estos dos predicados no sean los mismos en SQL:
...
Pero debe recordar las reglas para las funciones extremas: descarta todas las NULL antes de devolver los valores mayores o menores. El predicado ALL no arroja valores NULL, por lo que puede obtenerlos en los resultados.
(separador)
(315)
Sin embargo, la definición en el estándar está redactada en negativo, por lo que los NULL obtienen el beneficio de la duda. ...
Como puede ver, es una buena idea evitar valores NULL en restricciones ÚNICAS.
Discutiendo GROUP BY:
Los NULL se tratan como si fueran iguales entre sí y forman su propio grupo. Cada grupo se reduce a una sola fila en una nueva tabla de resultados que reemplaza a la anterior.
Esto significa que para la cláusula GROUP BY NULL = NULL no evalúa a NULL, como en 3VL, pero se evalúa como TRUE.
El estándar SQL es confuso:
ORDER BY y NULLs (329)
Si un valor de clave de clasificación que es NULL se considera mayor o menor que un valor no NULL está definido por la implementación, pero ...
... Hay productos SQL que lo hacen de cualquier manera.
En marzo de 1999, Chris Farrar sacó una pregunta de uno de sus desarrolladores que lo llevó a examinar una parte del SQL Standard que creí entender . Chris encontró algunas diferencias entre la comprensión general y la redacción actual de la especificación .
Y así. Creo que es suficiente por Celko.
CJ Fecha en SQL NULLs
CJ Date es más radical sobre NULLs: evita NULLs en SQL, punto. De hecho, el capítulo 4 de su SQL and Relational Theory: Cómo escribir código SQL preciso se titula "NO DUPLICADOS, NO NULLS", con los subcapítulos "4.4 ¿Qué hay de malo en los valores nulos?" y "4.5 Evitar valores nulos en SQL" (siga el enlace: gracias a Google Books, puede leer algunas páginas en línea).
Fabian Pascal en SQL NULLs
De sus Problemas prácticos en la administración de bases de datos: una referencia para el practicante de pensamiento (sin extractos en línea, perdón):
10.3 Implicaciones prácticas
10.3.1 SQL NULLs
... SQL sufre de los problemas inherentes a 3VL, así como de muchas peculiaridades, complicaciones, contrainteligencia y errores descarados [10, 11]; entre ellos están los siguientes:
- Las funciones agregadas (p. Ej., SUM (), AVG ()) ignoran los NULL (excepto por COUNT ()).
- Una expresión escalar en una tabla sin filas se evalúa incorrectamente en NULL, en lugar de 0.
- La expresión "NULL = NULL" se evalúa como NULL, pero en realidad no es válida en SQL; sin embargo, ORDER BY trata a los NULL como iguales (lo que sea que precedan o sigan a los valores "normales" se deja al vendedor del DBMS).
- La expresión "x IS NOT NULL" no es igual a "NOT (x IS NULL)", como es el caso en 2VL.
...
Todos los dialectos SQL implementados comercialmente siguen este enfoque de 3VL y, por lo tanto, no solo exiben estos problemas, sino que también tienen problemas específicos de implementación, que varían según los productos .
El concepto de NULL es cuestionable, por decir lo menos. Codd introdujo el modelo relacional y el concepto de NULL en contexto (¡y continuó proponiendo más de un tipo de NULL!) Sin embargo, la teoría relacional ha evolucionado desde las escrituras originales de Codd: algunas de sus propuestas han sido descartadas (por ejemplo, clave principal) y otros nunca atrapados (por ejemplo, operadores theta). En la teoría relacional moderna (teoría verdaderamente relacional, debo insistir) NULL simplemente no existe. Ver el Tercer Manifiesto. http://www.thethirdmanifesto.com/
El lenguaje SQL sufre el problema de la compatibilidad con versiones anteriores. NULL encontró su camino en SQL y estamos atrapados con él. Podría decirse que la implementación de NULL
en SQL es defectuosa (la implementación de SQL Server complica aún más las cosas debido a su opción ANSI_NULLS
).
Recomiendo evitar el uso de columnas NULLable en tablas base.
Aunque tal vez no debería caer en la tentación, solo quería hacer una corrección mía sobre cómo funciona NULL
en SQL:
NULL
= NULL
evalúa como UNKNOWN
.
UNKNOWN
es un valor lógico.
NULL
es un valor de datos.
Esto es fácil de probar, por ejemplo
SELECT NULL = NULL
genera correctamente un error en SQL Server. Si el resultado fue un valor de datos, esperaríamos ver NULL
, ya que algunas respuestas aquí (erróneamente) sugieren que lo haríamos.
El valor lógico UNKNOWN
se trata de manera diferente en SQL DML y SQL DDL, respectivamente.
En SQL DML, UNKNOWN
hace que las filas se eliminen del conjunto de resultados.
Por ejemplo:
CREATE TABLE MyTable
(
key_col INTEGER NOT NULL UNIQUE,
data_col INTEGER
CHECK (data_col = 55)
);
INSERT INTO MyTable (key_col, data_col)
VALUES (1, NULL);
El INSERT
tiene éxito para esta fila, aunque la condición CHECK
se resuelve en NULL = NULL
. Esto está definido en el estándar SQL-92 ("ANSI"):
11.6 definición de restricción de tabla
3)
Si la restricción de tabla es una definición de restricción de comprobación, entonces deje que SC sea la condición de búsqueda contenida inmediatamente en la definición de restricción de comprobación y sea T el nombre de tabla incluido en el descriptor de restricción de tabla correspondiente; la restricción de la tabla no se cumple si y solo si
EXISTS (SELECT * FROM T WHERE NOT (SC))
es verdad.
Lea eso otra vez cuidadosamente, siguiendo la lógica.
En lenguaje sencillo, a nuestra nueva fila de arriba se le da el ''beneficio de la duda'' acerca de ser UNKNOWN
y permitido pasar.
En SQL DML, la regla para la cláusula WHERE
es mucho más fácil de seguir:
La condición de búsqueda se aplica a cada fila de T. El resultado de la cláusula where es una tabla de esas filas de T para las cuales el resultado de la condición de búsqueda es verdadero.
En inglés simple, las filas que evalúan a UNKNOWN
se eliminan del conjunto de resultados.
En technet hay una buena explicación de cómo funcionan los valores nulos.
Nulo significa desconocido.
Por lo tanto, la expresión booleana
valor = nulo
no se evalúa como falso, se evalúa como nulo, pero si ese es el resultado final de una cláusula where, entonces no se devuelve nada. Esa es una forma práctica de hacerlo, ya que volver a cero sería difícil de concebir.
Es interesante y muy importante entender lo siguiente:
Si en una consulta tenemos
where (value=@param Or @param is null) And id=@anotherParam
y
- valor = 1
- @param es nulo
- id = 123
- @ anotherParam = 123
entonces
"value = @ param" se evalúa como nulo
"@param es nulo" se evalúa como verdadero
"id = @ anotherParam" se evalúa como verdadero
Entonces la expresión a ser evaluada se convierte
(nulo o verdadero) Y verdadero
Podríamos sentirnos tentados a pensar que aquí "nulo o verdadero" se evaluará como nulo y, por lo tanto, toda la expresión se vuelve nula y no se devolverá la fila.
Esto no es asi ¿Por qué?
Porque "nulo o verdadero" se evalúa como verdadero, lo cual es muy lógico, ya que si un operando es verdadero con el operador Or, entonces sin importar el valor del otro operando, la operación volverá a ser verdadera. Por lo tanto, no importa que el otro operando sea desconocido (nulo).
Entonces finalmente tenemos verdadero = verdadero y así la fila será devuelta.
Nota: con la misma lógica cristalina que "null O verdadero" se evalúa como verdadero, "nulo Y verdadero" se evalúa como nulo.
Actualizar:
Ok, solo para completarlo, quiero agregar aquí el resto, que resulta bastante divertido en relación con lo anterior.
"nulo O falso" se evalúa como nulo, "nulo y falso" se evalúa como falso. :)
La lógica es, por supuesto, tan evidente como antes.
La pregunta:
¿Un desconocido es igual a otro desconocido?
(NULL = NULL)
Esa pregunta es algo que nadie puede responder, por lo que su valor predeterminado es verdadero o falso según la configuración de ansi_nulls.
Sin embargo, la pregunta:
¿Es esta variable desconocida desconocida?
Esta pregunta es bastante diferente y se puede responder con verdadera.
nullVariable = null está comparando los valores
nullVariable is null está comparando el estado de la variable
MSDN tiene un buen article descriptivo sobre valores nulos y la lógica de tres estados que engendran.
En resumen, la especificación SQL92 define NULL como desconocido, y NUL utilizado en los siguientes operadores provoca resultados inesperados para los no iniciados:
= operator NULL true false
NULL NULL NULL NULL
true NULL true false
false NULL false true
and op NULL true false
NULL NULL NULL false
true NULL true false
false false false false
or op NULL true false
NULL NULL true NULL
true true true true
false NULL true false
NULL no es igual a nada, ni siquiera a sí mismo. Mi solución personal para comprender el comportamiento de NULL es evitar usarlo tanto como sea posible :).
Piense en el nulo como "desconocido" en ese caso (o "no existe"). En cualquiera de esos casos, no puede decir que son iguales, porque no conoce el valor de ninguno de ellos. Entonces, null = null se evalúa como no verdadero (falso o nulo, dependiendo de su sistema), porque no conoce los valores para decir que SON iguales. Este comportamiento se define en el estándar ANSI SQL-92.
EDITAR: Esto depende de su configuración ansi_nulls . si tiene ANSI_NULLS desactivado, esto SERÁ evaluado como verdadero. Ejecute el siguiente código para un ejemplo ...
set ansi_nulls off
if null = null
print ''true''
else
print ''false''
set ansi_nulls ON
if null = null
print ''true''
else
print ''false''
Porque NULL
significa ''valor desconocido'' y dos valores desconocidos no pueden ser iguales.
Entonces, si para nuestra lógica NULL
N ° 1 es igual a NULL
N ° 2, entonces tenemos que decir que de alguna manera:
SELECT 1
WHERE ISNULL(nullParam1, -1) = ISNULL(nullParam2, -1)
donde el valor conocido -1
N ° 1 es igual a -1
N ° 2
Solo porque no sepas qué son dos cosas, no significa que sean iguales. Si cuando piensas en NULL
piensas en "NULO" (cadena), entonces probablemente quieras una prueba de igualdad diferente a la de Postgresql. IS DISTINCT FROM
Y IS NOT DISTINCT FROM
http://www.postgresql.org/docs/8.4/static/functions-comparison.html
la expresión ES DISTINTA DE expresión
la expresión NO ES DISTINTA DE expresión
Para entradas no nulas, IS DISTINCT FROM es lo mismo que el operador <>. Sin embargo, si ambas entradas son nulas, devuelve falso, y si solo una entrada es nula, devuelve verdadero. De manera similar, IS NOT DISTINCT FROM es idéntico a = para entradas no nulas, pero devuelve true cuando ambas entradas son nulas, y false cuando solo una entrada es nula. Por lo tanto, estos constructos efectivamente actúan como si nulo fuera un valor de datos normal, en lugar de "desconocido".
Solo una adición a otras respuestas maravillosas:
AND: The result of true and unknown is unknown, false and unknown is false,
while unknown and unknown is unknown.
OR: The result of true or unknown is true, false or unknown is unknown, while unknown or unknown is unknown.
NOT: The result of not unknown is unknown
Tal vez eso dependa, pero pensé que NULL=NULL
evalúa como NULL
como la mayoría de las operaciones con NULL como operando.
null es desconocido en SQL, por lo que no podemos esperar que dos incógnitas sean iguales.
Sin embargo, puede obtener ese comportamiento estableciendo ANSI_NULLS en Desactivado (está Activado de manera predeterminada) Podrá usar = operador para valores nulos
SET ANSI_NULLS off
if null=null
print 1
else
print 2
set ansi_nulls on
if null=null
print 1
else
print 2
La confusión surge del nivel de indirección (abstracción) que se produce al usar NULL .
Volviendo a la analogía de "lo que está debajo del árbol de Navidad", "Desconocido" describe el estado del conocimiento sobre lo que está en el Cuadro A.
Entonces, si no sabes lo que hay en el Cuadro A, dices que es "Desconocido", pero eso no significa que "Desconocido" esté dentro del cuadro . Hay algo más que desconocido en la caja, posiblemente algún tipo de objeto, o posiblemente no haya nada en la caja.
De manera similar, si no sabe qué hay en el Cuadro B, puede etiquetar su estado de conocimiento sobre los contenidos como "Desconocido".
Así que aquí está el truco: su estado de conocimiento sobre el cuadro A es igual a su estado de conocimiento sobre el cuadro B. (Su estado de conocimiento en ambos casos es "Desconocido" o "No sé qué hay en la Caja".) Pero el contenido de las casillas puede ser igual o no.
Volviendo a SQL, lo ideal sería que solo pudieras comparar valores cuando sabes cuáles son. Desafortunadamente, la etiqueta que describe la falta de conocimiento se almacena en la propia celda , por lo que estamos tentados de usarla como un valor. Pero no deberíamos usar eso como un valor, porque conduciría a que "el contenido del recuadro A es igual al contenido del recuadro B cuando no sabemos qué hay en el recuadro A y / o no sabemos qué hay en el recuadro B. (Lógicamente, la implicación "si no sé lo que hay en el recuadro A y si no sé lo que hay en el recuadro B, entonces lo que está en el recuadro A = ¿Qué hay en el recuadro B?" Es falso).
Yay, Dead Horse.