【问题标题】:MYSQL - Group by name and include the according values of other columns in the resultsMYSQL - 按名称分组并在结果中包含其他列的相应值
【发布时间】:2017-12-02 18:18:48
【问题描述】:

首先,如果标题具有误导性,我想道歉。

我在mysql 中有一张名为products 的表:

+---------+-------+-----------+-------+
| name    | price | date      | brand |
+---------+-------+-----------+-------+
| apples  | 2     | 02/12/17  | Tesco |
| apples  | 1.95  | 28/11/17  | Aldi  |
| apples  | 2.5   | 29/11/17  | Lidl  |
| bananas | 0.5   | 01/12/17  | Tesco |
| bananas | 0.7   | 29/11/17  | Aldi  |
| bananas | 1     | 25/11/17  | Lidl  |
+---------+-------+-----------+-------+

如果我想从这个表中SELECTMAX 价格,我会继续执行这个查询:

SELECT
  products.name AS NAME,
  MAX(products.price) AS MAX_PRICE
FROM products
GROUP BY products.name;

哪个会输出:

+---------+-----------+
| NAME    | MAX_PRICE |
+---------+-----------+
| apples  | 2.5       |
| bananas | 1         |
+---------+-----------+

但是,我还想在查询输出中包含相应的日期和品牌,如下所示:

+---------+-----------+----------+-------+
| NAME    | MAX_PRICE | DATE     | BRAND |
+---------+-----------+----------+-------+
| apples  | 2.5       | 29/11/17 | Lidl  |
| bananas | 1         | 25/11/17 | Lidl  |
+---------+-----------+----------+-------+

MINSELECT 语句中也是如此:

+---------+-----------+----------+-------+
| NAME    | MAX_PRICE | DATE     | BRAND |
+---------+-----------+----------+-------+
| apples  | 1.95      | 28/11/17 | Aldi  |
| bananas | 0.5       | 01/12/17 | Tesco |
+---------+-----------+----------+-------+

这怎么能写成MySQL

【问题讨论】:

  • 这是一个常见问题 请参阅greatest-n-per-group 标签,了解过去的许多问题以及解决方案。

标签: mysql sql select group-by greatest-n-per-group


【解决方案1】:

我自己没有尝试过,但是如果您将 max 添加到日期,并将其添加到 group 子句中,就像这样 -

SELECT
  products.name AS NAME,
  MAX(products.price),MAX(products.date)  AS MAX_date,BRAND 
FROM products

GROUP BY products.name,products.date,BRAND ;

【讨论】:

    【解决方案2】:

    mySQL 具有使这些查询比标准 SQL 更简单的非标准功能:

      SELECT
      name AS NAME,
      MAX(products.price) AS MAX_PRICE, date, brand
      FROM products
      GROUP BY name;
    

    它将从子集中随机选择一个元组来获取日期和品牌。 如果从 {name, price} 到 {date, brand} 存在功能依赖 这相当于将日期和品牌添加到 group by。

    【讨论】:

      【解决方案3】:

      在没有group by 的情况下执行此操作。这是一种方法:

      select p.*
      from products p
      where p.price = (select max(p2.price) from products p2 where p2.name = p.name);
      

      这不仅是正确的,而且可以利用products(name, price) 上的索引。

      【讨论】:

        【解决方案4】:

        您只需加入结果即可获取结果中的其他行。

        SELECT p.name AS NAME,p.price AS MAX_PRICE, p.date as DATE, p.brand as BRAND 
        FROM products p JOIN 
        (
            SELECT brand, max(price) as brand_max_price 
            FROM products p
            GROUP BY brand
        ) t 
        ON p.brand = t.brand AND p.price = t.brand_max_price;
        

        【讨论】:

          【解决方案5】:

          您可以通过再次向同一个表添加连接来重复使用自己的查询。

          SELECT Z.NAME, Z.MAX_PRICE, A.DATE, A.BRAND
          FROM
          products A
          INNER JOIN
          (SELECT products.name AS NAME,  MAX(products.price) AS MAX_PRICE
          FROM products
          GROUP BY products.name) Z
          ON A.NAME = Z.NAME AND A.price = Z.MAX_PRICE;
          

          【讨论】:

            猜你喜欢
            • 2021-07-26
            • 2021-06-03
            • 2012-08-16
            • 2017-04-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-10-21
            • 1970-01-01
            相关资源
            最近更新 更多