3

有什么不同?

对:

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

错误的:

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)

内克尔

4

3 回答 3

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(这是错误的)。

于 2012-10-09T03:57:54.803 回答
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)
于 2012-10-09T04:05:09.437 回答
0
  1. ALL 是一个 Transact-SQL 扩展;并非所有数据库引擎都支持它。哎呀。
  2. 在谈论数据库时,性能是不可忽视的。该min解决方案可能会使用索引来非常快速地执行(假设 RDBMS 构建 B 树或类似的排序索引),而 all 解决方案强制进行全表扫描。
  3. 如果price允许为空,你会得到不同的答案。min忽略所有 null 值,因此如果price为 null,则 min 的结果将是一个数字。但是您的不同查询的结果将尝试将该 null 与所有价格进行比较,这将为每个价格返回,这意味着该子句UNKNOWN中没有价格匹配。where
于 2012-10-09T03:51:07.083 回答