子查询为2个几乎相同的查询返回不同的值

时间:2014-10-23 03:33:14

标签: mysql sql-server sql-server-2008 postgresql subquery

我对下面的查询及其返回值感到困惑。为什么在我在子查询中定义 recipe r 时只返回一个值,但在主查询中定义 recipe r 时返回20个值?造成差异的原因是什么?

首先查询:

SELECT   pizza, ingredient, amount 
FROM     recipe 
WHERE    amount = 
         (      SELECT Max(amount) 
                FROM   recipe r
                WHERE  ingredient=r.ingredient) 
ORDER BY ingredient;

  pizza  | ingredient | amount  
---------+------------+--------  
 seafood | seafood    |    200

第二次查询:

SELECT   pizza, ingredient, amount 
FROM     recipe r 
WHERE    amount= 
         (      SELECT max(amount) 
                FROM   recipe 
                WHERE  ingredient=r.ingredient) 
ORDER BY ingredient;

   pizza    | ingredient | amount  
------------+------------+--------   
 napolitana | anchovies  |    100
 special    | bacon      |     25
 cabanossi  | cabanossi  |    150
 siciliano  | capsicum   |     75
 mexicano   | capsicum   |     75
 margarita  | cheese     |    120
 mexicano   | chilli     |     25
 special    | egg        |     25
 garlic     | garlic     |     25
 ham        | ham        |    150
 mushroom   | mushroom   |    100
 napolitana | olives     |     75
 mexicano   | onion      |     75
 vegetarian | peas       |     50
 americano  | pepperoni  |     75
 hawaiian   | pineapple  |    100
 americano  | salami     |    120
 seafood    | seafood    |    200
 mexicano   | spice      |     20
 vegetarian | tomato     |     50

1 个答案:

答案 0 :(得分:3)

您的两个疑问是:

select pizza, ingredient, amount
from recipe
where amount = (select max(amount)
                from recipe r
                where ingredient = r.ingredient
               )
order by ingredient;

select pizza, ingredient, amount
from recipe r
where amount = (select max(amount)
                from recipe
                where ingredient = r.ingredient
                )
order by ingredient;

这两个都被称为相关子查询。但是,第一个是不相关的。在条件:

                where ingredient = r.ingredient

ingredient的两个引用都是内部查询中的表。所以,这基本上是一个无操作。更具体地说,它完全等同于where r.ingredient is not null。此内部查询返回单个值,即表中amount的最大值。

第二个版本是相关的,因此它返回每种成分的最大数量。

完全限定所有表名是一个很好的规则。您想要的查询应如下所示:

select r.pizza, r.ingredient, r.amount
from recipe r
where r.amount = (select max(r2.amount)
                  from recipe r2
                  where r2.ingredient = r.ingredient
                 )
order by r.ingredient;