SQL:在此查询中使用“all”和“min”的条件有何不同?

时间:2012-10-09 03:43:17

标签: sql

有什么不同?

RIGHT:

select distinct maker, price from product
inner join printer
on product.model = printer.model
where color = 'y' and price <= (select min(price) from printer where color = 'y')

WRONG:

select distinct maker, price from product
inner join printer
on product.model = printer.model
where color = 'y' and price <= all (select distinct price from printer where color = 'y')

我知道使用“min”表现更好。 但是,任何人都可以解释结果中的错误和不同吗?

表格结构:

Product(maker, model, type)
Printer(code, model, color, type, price)

neikel

3 个答案:

答案 0 :(得分:1)

如果存在NULL printers.price,则第二个将失败。考虑一下(我在这里使用PostgreSQL):

=> select 0 <= (select min(x) from (values (null), (1), (2)) as t(x));
 ?column? 
----------
 t
(1 row)

和此:

=> select 0 <= all (select x from (values (null), (1), (2)) as t(x));
 ?column? 
----------

(1 row)

这是第一种情况下的真实结果,第二种情况是NULL(假)。

答案 1 :(得分:1)

ALL 是一种简短形式,用于将比较运算符扩展为所有行,并将条件与AND组合。
ANY 是一种简短形式,用于将比较运算符与所有行进行扩展,并将条件与OR组合。

具体地,

price <= all (select distinct price from printer where color = 'y')

扩展为,假设子查询返回4行

price <= <price1> AND
price <= <price2> AND
price <= <price3> AND
price <= <price4>

当其中任何一个恢复为NULL时,结果为 false ,因为使用<=无法比较NULL。 MIN没有这个问题(因为MIN跳过NULL),除了没有结果行的边缘情况,在这种情况下<= (select MIN..)也会给你一个意想不到的结果。

使用ALL in对可空列执行测试应几乎总是使用过滤器进行限定,例如

select distinct maker, price from product
inner join printer
on product.model = printer.model
where color = 'y' and price <=
      all (select distinct price from printer where color = 'y'
           where price is not null)

答案 2 :(得分:0)

  1. ALL是Transact-SQL扩展;所有数据库引擎都不支持它。糟糕。
  2. 谈论数据库时,性能不容忽视。 min解决方案可能使用索引来非常快速地执行(假设RDBMS构建了B树或类似的排序索引),而all解决方案强制进行全表扫描。
  3. 如果允许price为空,您将获得不同的答案。 min忽略所有空值,因此如果price为null,则min的结果将是一个数字。但是,您的独特查询的结果将尝试将该null与所有价格进行比较,这将为每个价格返回UNKNOWN,这意味着where子句中的价格不会匹配。