有什么不同?
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
答案 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)
min
解决方案可能使用索引来非常快速地执行(假设RDBMS构建了B树或类似的排序索引),而all解决方案强制进行全表扫描。price
为空,您将获得不同的答案。 min
忽略所有空值,因此如果price
为null,则min的结果将是一个数字。但是,您的独特查询的结果将尝试将该null与所有价格进行比较,这将为每个价格返回UNKNOWN
,这意味着where
子句中的价格不会匹配。