mysql取每个分类前5个逐步分析

之前面试面到过,也是搜了好久,发现可以用加行号的方式解决该问题
首先有一张表,有三个字段goods,name,price,有这样一个需求:
需要查询每个人购买最贵的5个商品有哪些?
分析:(也就是按人名分类取出前5个贵的商品)
表结构:
在这里插入图片描述
插入语句:

insert into shopping (goods, name, price) VALUES ("笔","小明",20.00);
insert into shopping (goods, name, price) VALUES ("杯子","小明",100.00);
insert into shopping (goods, name, price) VALUES ("花","小红",10.00);
insert into shopping (goods, name, price) VALUES ("车子","小红",100000.00);
insert into shopping (goods, name, price) VALUES ("房子","小王",1000000.00);
insert into shopping (goods, name, price) VALUES ("狗","小王",1000.00);
insert into shopping (goods, name, price) VALUES ("1","小王",1.00);
insert into shopping (goods, name, price) VALUES ("2","小王",10.00);
insert into shopping (goods, name, price) VALUES ("3","小王",100.00);
insert into shopping (goods, name, price) VALUES ("4","小王",1000.00);
insert into shopping (goods, name, price) VALUES ("5","小王",10000.00);
insert into shopping (goods, name, price) VALUES ("6","小王",0.100);

逐步解析:
1.刚开始看到这个查询需求的第一想法是先按name分组,但group by name分组只会将name这一列分组,而price其实是取了按表中顺序取了每个分组的最上面一个,可以对照上面的表看
实验结果:
在这里插入图片描述
所以这里用group by是不可取的
2.那如果要得到这个分类,怎么办呢,可以先按人名升序,再按价格降序,也就是这样一张表:
在这里插入图片描述
3.但是我们还需要取出这个分类的每前5个,又怎么取呢?
其实如果将每个分类添加分组行号,再取rownum<=5的行,其实就可以将前5个取出来了,即为这样,先添加行号:
在这里插入图片描述
再取前5个:
在这里插入图片描述
这样就查询出了每个人购买最贵的5个商品的结果:
这里完整的查询语句为:

select goods,name,price
    from (
        select
            @gn:=case when @name=name then @gn+1 else 1 end rownum,
            price,
            goods,
            @name:=name as name
        from shopping a ,(select @gn:=0,@name:=(select name from shopping order by name,price desc limit 1)) b
        order by name,price desc) aa
    where rownum<=5;

最后解释一下这里查询语句的含义:
首先可以尝试:
select @rowNum:=0;
该句表示将0赋值给变量rowNum
然后尝试:
select @rowNum:=@rowNum+1,a.* from shopping a ,(select @rowNum:=0) b;
这里我理解为rowNum可以看做为一个全局变量,第一次赋值为0,当查询第一行时rowNum赋值为1,和a表的字段相联;查询第二行时rowNum赋值为2,和a表的字段相联,以此类推,,,
实验结果:
在这里插入图片描述
最后尝试该查询,

  select
            @gn:=case when @name=name then @gn+1 else 1 end rownum,
            price,
            goods,
            @name:=name as name
        from shopping a ,(select @gn:=0,@name:=(select name from shopping order by name,price desc limit 1)) b
        order by name,price desc

首先name第一次赋值为排序后最上面的“小明”,然后查询到shopping的第一行时,@name的这个变量name此时值为“小明”,而name字段此时也为小明,gn=1,注意此时@name变量这里赋值的顺序是在判断语句后,也就是判断以后,第一行字段name的值“小明”又赋值给了@name,所以在第二行时@name的值为“小明”,name的值也为小明,此时gn+1=2,而到第三行时,此时@name的值为“小明”,而字段name的值变成了小王,所以gn此时就走到else,又变成了1,就实现了分组行号了*^^*

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_36875803/article/details/111408225
今日推荐