zoukankan      html  css  js  c++  java
  • mysql分组取每组前几条记录(排序)

    表mygoods为商品表,cat_id为分类id,goods_id为商品id,status为商品当前的状态位(1:有效,0:无效)。

    CREATE TABLE `mygoods` (  
      `goods_id` int(11) unsigned NOT NULL AUTO_INCREMENT,  
      `cat_id` int(11) NOT NULL DEFAULT '0',  
      `price` tinyint(3) NOT NULL DEFAULT '0',  
      `status` tinyint(3) DEFAULT '1',  
      PRIMARY KEY (`goods_id`),  
      KEY `icatid` (`cat_id`)  
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;  
      
    INSERT INTO `mygoods` VALUES (1, 101, 90, 0);  
    INSERT INTO `mygoods` VALUES (2, 101, 99, 1);  
    INSERT INTO `mygoods` VALUES (3, 102, 98, 0);  
    INSERT INTO `mygoods` VALUES (4, 103, 96, 0);  
    INSERT INTO `mygoods` VALUES (5, 102, 95, 0);  
    INSERT INTO `mygoods` VALUES (6, 102, 94, 1);  
    INSERT INTO `mygoods` VALUES (7, 102, 93, 1);  
    INSERT INTO `mygoods` VALUES (8, 103, 99, 1);  
    INSERT INTO `mygoods` VALUES (9, 103, 98, 1);  
    INSERT INTO `mygoods` VALUES (10, 103, 97, 1);  
    INSERT INTO `mygoods` VALUES (11, 104, 96, 1);  
    INSERT INTO `mygoods` VALUES (12, 104, 95, 1);  
    INSERT INTO `mygoods` VALUES (13, 104, 94, 1);  
    INSERT INTO `mygoods` VALUES (15, 101, 92, 1);  
    INSERT INTO `mygoods` VALUES (16, 101, 93, 1);  
    INSERT INTO `mygoods` VALUES (17, 101, 94, 0);  
    INSERT INTO `mygoods` VALUES (18, 102, 99, 1);  
    INSERT INTO `mygoods` VALUES (19, 105, 85, 1);  
    INSERT INTO `mygoods` VALUES (20, 105, 89, 0);  
    INSERT INTO `mygoods` VALUES (21, 105, 99, 1);

    先查出分组后的有效商品

    SELECT
        a.* 
    FROM
        mygoods a 
    WHERE
        a.`status` = 1 
    GROUP BY
        a.cat_id,
        a.goods_id,
        a.price 
    ORDER BY
        cat_id;
    
    +----------+--------+-------+--------+
    | goods_id | cat_id | price | status |
    +----------+--------+-------+--------+
    |        2 |    101 |    99 |      1 |
    |       15 |    101 |    92 |      1 |
    |       16 |    101 |    93 |      1 |
    |        6 |    102 |    94 |      1 |
    |        7 |    102 |    93 |      1 |
    |       18 |    102 |    99 |      1 |
    |        8 |    103 |    99 |      1 |
    |        9 |    103 |    98 |      1 |
    |       10 |    103 |    97 |      1 |
    |       11 |    104 |    96 |      1 |
    |       12 |    104 |    95 |      1 |
    |       13 |    104 |    94 |      1 |
    |       19 |    105 |    85 |      1 |
    |       21 |    105 |    99 |      1 |
    +----------+--------+-------+--------+

    需求一:每个分类下,找出两个价格最高的有效的商品。

    1. 每个分类找出价格最高的两个商品(错误,没有满足有效商品)

    复制代码
    mysql> select a.*   
        -> from mygoods a   
        -> where (select count(*) 
        -> from mygoods 
        -> where cat_id = a.cat_id and price > a.price  ) <2 
        -> order by a.cat_id,a.price desc;
    +----------+--------+-------+--------+
    | goods_id | cat_id | price | status |
    +----------+--------+-------+--------+
    |        2 |    101 |    99 |      1 |
    |       17 |    101 |    94 |      0 |
    |       18 |    102 |    99 |      1 |
    |        3 |    102 |    98 |      0 |
    |        8 |    103 |    99 |      1 |
    |        9 |    103 |    98 |      1 |
    |       11 |    104 |    96 |      1 |
    |       12 |    104 |    95 |      1 |
    |       21 |    105 |    99 |      1 |
    |       20 |    105 |    89 |      0 |
    +----------+--------+-------+--------+
    10 rows in set (0.00 sec)

    2. 每个分类找出价格最高的有效的两个商品(正确)

    a商品价格的最大值小于b商品价格的个数为0

    SELECT
        a.* 
    FROM
        mygoods a 
    WHERE
        (
        SELECT
            count( 1 ) 
        FROM
            mygoods b
        WHERE
            a.cat_id = b.cat_id 
            AND b.price > a.price 
            AND b.`status` = 1 
        )< 2 
        AND a.`status` = 1 
    ORDER BY
        a.cat_id,
        a.price DESC

    +----------+--------+-------+--------+ | goods_id | cat_id | price | status | +----------+--------+-------+--------+ | 2 | 101 | 99 | 1 | | 16 | 101 | 93 | 1 | | 18 | 102 | 99 | 1 | | 6 | 102 | 94 | 1 | | 8 | 103 | 99 | 1 | | 9 | 103 | 98 | 1 | | 11 | 104 | 96 | 1 | | 12 | 104 | 95 | 1 | | 21 | 105 | 99 | 1 | | 19 | 105 | 85 | 1 | +----------+--------+-------+--------+ 10 rows in set (0.00 sec)

    3. 每个分类找出价格最高的有效的两个商品(正确)

    a商品价格的最大值小于b商品价格的个数为0

    SELECT
        a.*
    FROM
        mygoods a
        LEFT JOIN mygoods b ON a.cat_id = b.cat_id 
        AND a.price < b.price 
        AND b.`status` = 1 
    WHERE
        a.`status` = 1 
    GROUP BY
        a.goods_id,
        a.cat_id,
        a.price 
    HAVING
        count( b.goods_id ) < 2
    ORDER BY
        a.cat_id,
        a.price DESC;
    
    +----------+--------+-------+--------+
    | goods_id | cat_id | price | status |
    +----------+--------+-------+--------+
    |        2 |    101 |    99 |      1 | 
    |       16 |    101 |    93 |      1 | 
    |       18 |    102 |    99 |      1 | 
    |        6 |    102 |    94 |      1 | 
    |        8 |    103 |    99 |      1 | 
    |        9 |    103 |    98 |      1 | 
    |       11 |    104 |    96 |      1 | 
    |       12 |    104 |    95 |      1 | 
    |       21 |    105 |    99 |      1 | 
    |       19 |    105 |    85 |      1 | 
    +----------+--------+-------+--------+
    10 rows in set (0.00 sec)

    4.每个分类找出价格最高的有效的两个商品(错误)

    SELECT
        a.* 
    FROM
        mygoods a 
    WHERE
        (
        SELECT
            count( * ) 
        FROM
            mygoods b
        WHERE
            a.cat_id = b.cat_id 
            AND b.price > a.price 
        )< 2 
        AND a.`status` = 1 
    ORDER BY
        a.cat_id,
        a.price DESC
    
    +----------+--------+-------+--------+
    | goods_id | cat_id | price | status |
    +----------+--------+-------+--------+
    |        2 |    101 |    99 |      1 |
    |       18 |    102 |    99 |      1 |
    |        8 |    103 |    99 |      1 |
    |        9 |    103 |    98 |      1 |
    |       11 |    104 |    96 |      1 |
    |       12 |    104 |    95 |      1 |
    |       21 |    105 |    99 |      1 |
    +----------+--------+-------+--------+
    7 rows in set (0.00 sec)

    需求二:每个分类下,找出两个价格最低的有效的商品。

    方法一:

    SELECT
        a.* 
    FROM
        mygoods a 
    WHERE
        (
        SELECT
            count( * ) 
        FROM
            mygoods b
        WHERE
            a.cat_id = b.cat_id 
            AND b.price < a.price 
            AND b.`status` = 1 
        )< 2 
        AND a.`status` = 1 
    ORDER BY
        a.cat_id,
        a.price DESC

    +----------+--------+-------+--------+
    | goods_id | cat_id | price | status |
    +----------+--------+-------+--------+
    |       16 |    101 |    93 |      1 |
    |       15 |    101 |    92 |      1 |
    |        6 |    102 |    94 |      1 |
    |        7 |    102 |    93 |      1 |
    |        9 |    103 |    98 |      1 |
    |       10 |    103 |    97 |      1 |
    |       12 |    104 |    95 |      1 |
    |       13 |    104 |    94 |      1 |
    |       21 |    105 |    99 |      1 |
    |       19 |    105 |    85 |      1 |
    +----------+--------+-------+--------+
    10 rows in set (0.00 sec)

    方法二:

    SELECT
        a.* 
    FROM
        mygoods a
        LEFT JOIN mygoods b ON a.cat_id = b.cat_id 
        AND a.price > b.price 
        AND b.`status` = 1 
    WHERE
        a.`status` = 1 
    GROUP BY
        a.goods_id,
        a.cat_id,
        a.price 
    HAVING
        count( b.goods_id ) < 2 
    ORDER BY
        a.cat_id,
        a.price DESC;
    
    +----------+--------+-------+--------+
    | goods_id | cat_id | price | status |
    +----------+--------+-------+--------+
    |       16 |    101 |    93 |      1 |
    |       15 |    101 |    92 |      1 |
    |        6 |    102 |    94 |      1 |
    |        7 |    102 |    93 |      1 |
    |        9 |    103 |    98 |      1 |
    |       10 |    103 |    97 |      1 |
    |       12 |    104 |    95 |      1 |
    |       13 |    104 |    94 |      1 |
    |       21 |    105 |    99 |      1 |
    |       19 |    105 |    85 |      1 |
    +----------+--------+-------+--------+

    需求三:每个分类下,找出价格最高的有效商品。

    方法一:

    SELECT
        a.* 
    FROM
        mygoods a 
    WHERE
        a.price = ( SELECT max( b.price ) FROM mygoods b WHERE a.cat_id = b.cat_id AND b.`status` = 1 ) 
        AND a.`status` = 1 
    ORDER BY
        a.cat_id;
    
    +----------+--------+-------+--------+
    | goods_id | cat_id | price | status |
    +----------+--------+-------+--------+
    |        2 |    101 |    99 |      1 |
    |       18 |    102 |    99 |      1 |
    |        8 |    103 |    99 |      1 |
    |       11 |    104 |    96 |      1 |
    |       21 |    105 |    99 |      1 |
    +----------+--------+-------+--------+
    5 rows in set (0.00 sec)

    方法二:

    SELECT
        a.* 
    FROM
        mygoods a 
    WHERE
        (
        SELECT
            count(1) 
        FROM
            mygoods b 
        WHERE
            a.cat_id = b.cat_id 
            AND a.price < b.price 
            AND b.`status` = 1 
        )= 0  //<1
        AND a.`status` = 1 
    ORDER BY
        a.cat_id,
        a.price DESC;
    
    +----------+--------+-------+--------+
    | goods_id | cat_id | price | status |
    +----------+--------+-------+--------+
    |        2 |    101 |    99 |      1 |
    |       18 |    102 |    99 |      1 |
    |        8 |    103 |    99 |      1 |
    |       11 |    104 |    96 |      1 |
    |       21 |    105 |    99 |      1 |
    +----------+--------+-------+--------+
    5 rows in set (0.00 sec)

     方法三:

    SELECT
        a.* 
    FROM
        mygoods a
        LEFT JOIN mygoods b ON a.cat_id = b.cat_id 
        AND a.price < b.price 
        AND b.`status` = 1 
    WHERE
        a.`status` = 1 
    GROUP BY
        a.goods_id,
        a.cat_id,
        a.price 
    HAVING
        count( b.goods_id ) = 0 //<1
    ORDER BY
        a.cat_id,
        a.price DESC;
    
    +----------+--------+-------+--------+
    | goods_id | cat_id | price | status |
    +----------+--------+-------+--------+
    |        2 |    101 |    99 |      1 |
    |       18 |    102 |    99 |      1 |
    |        8 |    103 |    99 |      1 |
    |       11 |    104 |    96 |      1 |
    |       21 |    105 |    99 |      1 |
    +----------+--------+-------+--------+
    5 rows in set (0.00 sec)

    具体的原理本人没搞清楚,谁有比较好的思路可以交流下

    参考文章:

    mysql分组取每组前几条记录(排序)

  • 相关阅读:
    Eclipse连接MySQL数据库(傻瓜篇)
    JMeter监控内存及CPU ——plugin插件监控被测系统资源方法
    fiddler抓取手机端的数据流量包
    python 字典(dictionary)一些方法
    python 循环语句
    Charles 抓 HTTPS 包
    python RSA 加密与签名
    从零开始做一个Jmeter性能测试
    [python之路]变量和字符编码
    [python之路]简单介绍
  • 原文地址:https://www.cnblogs.com/zheaven/p/15476164.html
Copyright © 2011-2022 走看看