Esta es la consulta que tengo actualmente:

select * from outerb where not exists(
Select * from wms
where wms.barcode = outerb.barcode);

Esta consulta me devuelve los valores que necesito.

Hasta ahora tan buena ...

Luego, necesitaba seleccionar una columna específica (en este caso pcode) que no tiene valores escritos allí. Esto es lo que he intentado y funcionó absolutamente bien para mí:

select * from outerb where not exists(
Select * from wms
where wms.barcode = outerb.barcode) 
and pcode = "" or pcode is null;

Pero cuando agrego otra columna a la consulta, me devuelve una columna vacía para pcode pero para la nueva columna, me devuelve valores vacíos y con valores rellenos. De lo que estoy confundido. Esto es lo que he intentado:

select * from outerb where not exists(
Select * from wms
where wms.barcode = outerb.barcode) 
and pcode = "" or pcode is null
and
brand = "" or brand is null;

Pcode funciona absolutamente bien pero brand no ... ¿cuál es el problema?

Pero si invierto los dos, entonces brand viene primero en la consulta y pcode viene segundo, es pcode esta vez que aparece con valores y brand sin valores.

Ambas columnas son del tipo Varchar

0
user11327799 10 may. 2019 a las 13:27

4 respuestas

La mejor respuesta

Pon algunos corchetes en

select * 
from outerb 
where 
  not exists(
   select * 
   from wms
   where 
     wms.barcode = outerb.barcode
  ) 
  and (pcode = '' or pcode is null)
  and (brand = '' or brand is null);

Siempre que mezcle AND y OR, use corchetes para dejar en claro tanto al DB como a la persona que mantiene esto después de usted, qué conjunto de verdades van juntas. Sin ellos, MySQL primero evaluará cualquier AND y luego evaluará cualquier OR. Esto significa cuando dices:

a AND b OR c AND d OR e

MySQL hará, frente a lo que quería:

(a AND b) OR (c AND d) OR e --MySQL does
a AND (b OR c) AND (d OR e) --you wanted

Un conjunto muy diferente de verdades, esos dos

Eche un vistazo a Mysql o / y precedencia? para obtener más información

Nota al pie de página de Tim y un consejo general al trabajar con MySQL: MySQL puede ser un poco como Visual Basic 6- en su configuración predeterminada, le permite ser un poco más descuidado con su codificación que la mayoría de las demás bases de datos. Cosas como no tener que proporcionar un GROUP BY explícito en una consulta que usa agregados; solo inventará una agrupación para ti. También permite el uso de comillas dobles para cadenas cuando el estándar SQL es comillas simples. El estándar SQL usa comillas dobles para citar nombres de columnas, etc., por lo que SELECT a as "my column name with spaces" - MySQL permite que las cadenas también se doblen, lo cual no es especifico. Entonces, ¿por qué apegarse a las especificaciones? Hace que sus habilidades en la base de datos sean mucho más portátiles: si aprende sql estándar, funciona en más lugares que el sql específico de MySQL, significa que puede decir con mayor confianza en una entrevista de trabajo que la habilidad cruzada de su base de datos es buena porque ha utilizado un rango de bases de datos enfocando su aprendizaje en el estándar sql, en lugar de decir "Solo he usado MySQL pero estoy seguro de que puedo aprender ...". Por supuesto, siempre se encontrará con cosas específicas del proveedor, ya que el estándar no cumple con la demanda del consumidor como lo hacen las implementaciones. Nota al margen; Creo que Postgres es una de las mejores bases de datos para el cumplimiento estricto de las especificaciones SQL y, por lo tanto, es una buena base de datos de aprendizaje

1
Caius Jard 11 may. 2019 a las 04:51

No puede mezclar OR y AND sin especificar lo que está agrupado. Use corchetes para agruparlos.

select * from outerb where not exists(
Select * from wms
where wms.barcode = outerb.barcode) 
and (pcode = "" or pcode is null)
and
(brand = "" or brand is null;)
0
AliIshaq 10 may. 2019 a las 10:30

Agregar soporte a su consulta

select * from outerb where not exists(
Select * from wms
where wms.barcode = outerb.barcode) 
and 
(pcode = "" or pcode is null)
and
(brand = "" or brand is null);
0
gauri 10 may. 2019 a las 10:32

Este es probablemente un problema de orden de operaciones con AND que tiene mayor prioridad que OR. Prueba esta versión:

SELECT *
FROM outerb
WHERE NOT EXISTS (SELECT 1 FROM wms WHERE wms.barcode = outerb.barcode) AND
    (pcode = '' OR pcode IS NULL) AND
    (brand = '' OR brand IS NULL);

Pero, en realidad podríamos simplificar para evitar este problema por completo, usando COALESCE:

SELECT *
FROM outerb
WHERE NOT EXISTS (SELECT 1 FROM wms WHERE wms.barcode = outerb.barcode) AND
    COALESCE(pcode, '') = '' AND
    COALESCE(brand, '') = '';
1
Tim Biegeleisen 10 may. 2019 a las 10:31