美文网首页
MySQL如何查询每个分组里第一条、最后一条、最大一条的数据

MySQL如何查询每个分组里第一条、最后一条、最大一条的数据

作者: wuxuan94 | 来源:发表于2017-09-25 18:00 被阅读0次

    这篇文章将带着大家解决查询top N的数据,不仅仅是最高或者最低的一条。
    一、准备工作
    创建如下表并添加数据:

    +--------+------------+-------+
    | type   | variety    | price |
    +--------+------------+-------+
    | apple  | gala       |  2.79 | 
    | apple  | fuji       |  0.24 | 
    | apple  | limbertwig |  2.87 | 
    | orange | valencia   |  3.59 | 
    | orange | navel      |  9.36 | 
    | pear   | bradford   |  6.05 | 
    | pear   | bartlett   |  2.14 | 
    | cherry | bing       |  2.55 | 
    | cherry | chelan     |  6.33 | 
    +--------+------------+-------+
    

    二、查询
    1.查询每类水果里最便宜的

    +--------+----------+-------+
    | type   | variety  | price |
    +--------+----------+-------+
    | apple  | fuji     |  0.24 | 
    | orange | valencia |  3.59 | 
    | pear   | bartlett |  2.14 | 
    | cherry | bing     |  2.55 | 
    +--------+----------+-------+
    

    和其他查询极值的sql一样分为两步:第一步找到最符合条件的price,第二步查询符合这个条件其他列的数据。

    自连接
    1.找出每类水果里价格最便宜的

    select type, min(price) as minprice
    from fruits
    group by type;
    +--------+----------+
    | type   | minprice |
    +--------+----------+
    | apple  |     0.24 | 
    | cherry |     2.55 | 
    | orange |     3.59 | 
    | pear   |     2.14 | 
    +--------+----------+
    

    2.通过查询相同表join上一步结果找出其余列

    select f.type, f.variety, f.price
    from (
       select type, min(price) as minprice
       from fruits group by type
    ) as x inner join fruits as f on f.type = x.type and f.price = x.minprice;
    +--------+----------+-------+
    | type   | variety  | price |
    +--------+----------+-------+
    | apple  | fuji     |  0.24 | 
    | cherry | bing     |  2.55 | 
    | orange | valencia |  3.59 | 
    | pear   | bartlett |  2.14 | 
    +--------+----------+-------+
    

    相关子查询(效率较低)

    select type, variety, price
    from fruits
    where price = (select min(price) from fruits as f where f.type = fruits.type);
    +--------+----------+-------+
    | type   | variety  | price |
    +--------+----------+-------+
    | apple  | fuji     |  0.24 | 
    | orange | valencia |  3.59 | 
    | pear   | bartlett |  2.14 | 
    | cherry | bing     |  2.55 | 
    +--------+----------+-------+
    

    二、查询每组TOP N的几行数据
    查询每类水果里最便宜的两个数据,这是第一次尝试

    select type, variety, price
    from fruits
    where price = (select min(price) from fruits as f where f.type = fruits.type)
       or price = (select min(price) from fruits as f where f.type = fruits.type
          and price > (select min(price) from fruits as f2 where f2.type = fruits.type));
    +--------+----------+-------+
    | type   | variety  | price |
    +--------+----------+-------+
    | apple  | gala     |  2.79 | 
    | apple  | fuji     |  0.24 | 
    | orange | valencia |  3.59 | 
    | orange | navel    |  9.36 | 
    | pear   | bradford |  6.05 | 
    | pear   | bartlett |  2.14 | 
    | cherry | bing     |  2.55 | 
    | cherry | chelan   |  6.33 | 
    +--------+----------+-------+
    

    当查询TOP 3、TOP4..时这个方法会很难用
    这里有一个跟好的方法:

    select type, variety, price
    from fruits
    where (
       select count(*) from fruits as f
       where f.type = fruits.type and f.price <= fruits.price
    ) <= 2;
    

    这个方法更简洁、方便,但是它和上面的方法机制上是一样的,这两个从本质上来讲都是关于水果种类的二次计算。
    使用UNION

    (select * from fruits where type = 'apple' order by price limit 2)
    union all
    (select * from fruits where type = 'orange' order by price limit 2)
    union all
    (select * from fruits where type = 'pear' order by price limit 2)
    union all
    (select * from fruits where type = 'cherry' order by price limit 2)
    

    需要注意的是:用union all而不是union

    相关文章

      网友评论

          本文标题:MySQL如何查询每个分组里第一条、最后一条、最大一条的数据

          本文链接:https://www.haomeiwen.com/subject/fwltextx.html