选择不存在数据的位置并选择为空或为空的列-MySQL

时间:2019-05-10 10:27:17

标签: mysql mysql-workbench

这是我当前拥有的查询:

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

此查询返回我所需的值。

到目前为止一切都很好...

接下来,我需要选择一个没有在其中写入任何值的特定列(在本例中为pcode)。这是我尝试过的方法,对我来说绝对不错:

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

但是,当我向查询添加另一列时,它为我返回pcode的空列,但对于新列,它返回了空值并填充了值。我对此感到困惑。这是我尝试过的:

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绝对可以,但是brand不能。.是什么问题?

但是如果我将两者取反,那么brand在查询中排在第一位,而pcode在查询中排在第二位,这次它的pcode用值显示,而brand却没有显示值。

两列都是Varchar类型

4 个答案:

答案 0 :(得分:2)

放入一些括号

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);

每当您将AND和OR混合使用时,请使用方括号向DB和在您之后维护此问题的人员明确说明,这是一组真理。没有它们,MySQL将首先评估任何AND,然后评估任何OR。这意味着当您说:

a AND b OR c AND d OR e

MySQL可以满足您的需求:

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

这两组真相非常不同

看看Mysql or/and precedence?了解更多信息

Tim的脚注和使用MySQL时的一般建议-MySQL的默认设置可能有点像Visual Basic 6-与大多数其他数据库相比,它使您的编码更加草率。诸如不必在使用聚合的查询上提供显式GROUP BY之类的事情;它只会为您创建分组。当SQL标准是单引号时,它还允许对字符串使用双引号。 SQL标准使用双引号来引用列名等,因此SELECT a as "my column name with spaces"-MySQL允许字符串也被双引号,这不是规范。那么为什么要坚持规格呢?它使您的数据库技能更易于移植-如果您学习标准sql,它的工作范围比MySQL特定的sql多,这意味着您可以在求职面试中更有信心地说,您的数据库交叉技能很好,因为您使用过一系列通过将学习重点放在sql标准上来访问数据库,而不是说“我只使用过MySQL,但我确定我可以学习..”。当然,您总是会遇到供应商特定的问题,因为该标准不能像实现那样跟上消费者的需求。边注;我相信Postgres是严格遵守SQL规范的较好数据库之一,因此可以构成一个学习良好的数据库

答案 1 :(得分:2)

这可能是一个操作顺序问题,其中AND的优先级高于OR。试试这个版本:

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);

但是,实际上,我们可以使用COALESCE简化为完全避免此问题:

SELECT *
FROM outerb
WHERE NOT EXISTS (SELECT 1 FROM wms WHERE wms.barcode = outerb.barcode) AND
    COALESCE(pcode, '') = '' AND
    COALESCE(brand, '') = '';

答案 2 :(得分:1)

如果不指定分组内容,则不能将ORAND混合在一起。使用方括号将它们分组。

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;)

答案 3 :(得分:1)

在查询中添加括号

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);