这是我当前拥有的查询:
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类型
答案 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)
如果不指定分组内容,则不能将OR
和AND
混合在一起。使用方括号将它们分组。
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);