【问题标题】:Will grouping an ordered table always return the first row? MYSQL对有序表进行分组是否总是返回第一行? MYSQL
【发布时间】:2011-05-02 07:56:33
【问题描述】:

我正在编写一个查询,我在其中对一组行进行分组以查找其中一列的 MIN 值。

我还想返回与返回的 MIN 行关联的其他列值。

例如

ID QTY PRODUCT TYPE
--------------------
1  2   Orange  Fruit
2  4   Banana  Fruit
3  3   Apple   Fruit

如果我按“类型”列对表进行分组并选择最小数量,它将不会返回最小行的相应产品,在上面的例子中是“苹果”。

在分组之前添加 ORDER BY 子句似乎可以解决问题。但是,在我继续在我的应用程序中包含这个查询之前,我只想知道这个方法是否总是会返回正确的值。这是正确的方法吗?我见过一些使用子查询的例子,但我也读到过这种做法效率低下。

提前致谢。

【问题讨论】:

    标签: mysql


    【解决方案1】:

    在分组之前添加 ORDER BY 子句似乎可以解决问题。但是,在我继续在我的应用程序中包含这个查询之前,我只想知道这个方法是否总是会返回正确的值。这是正确的方法吗?我见过一些使用子查询的例子,但是我也读到这效率低下。

    不,这不是正确的方法。

    我相信您在谈论这样的查询:

    SELECT  product.*, MIN(qty)
    FROM    product
    GROUP BY
            type
    ORDER BY
            qty
    

    您在这里所做的是使用MySQL 的扩展程序,它允许您在GROUP BY 查询中选择未聚合/未分组的列。

    这主要用于在PRIMARY KEY 上同时包含JOINGROUP BY 的查询中,如下所示:

    SELECT  order.id, order.customer, SUM(price)
    FROM    order
    JOIN    orderline
    ON      orderline.order_id = order.id
    GROUP BY
            order.id
    

    这里,order.customer 既没有分组也没有聚合,但由于您是在 order.id 上进行分组,因此可以保证在每个组中具有相同的值。

    在您的情况下,qty 的所有值在组内都有不同的值。

    不保证引擎将从组内的哪个记录中获取值。

    你应该这样做:

    SELECT  p.*
    FROM    (
            SELECT  DISTINCT type
            FROM    product p
            ) pd
    JOIN    p
    ON      p.id = 
            (
            SELECT  pi.id
            FROM    product pi
            WHERE   pi.type = pd.type
            ORDER BY
                    type, qty, id
            LIMIT 1
            )
    

    如果您在product (type, qty, id) 上创建索引,此查询将运行得很快。

    【讨论】:

    • 谢谢!这是一个非常有用的答案,查询效果很好。
    【解决方案2】:

    如果没有您尝试的查询示例,很难正确地关注您。 从你的 cmets 我猜你查询类似,

    SELECT ID, COUNT(*) AS QTY, PRODUCT_TYPE 
        FROM PRODUCTS
        GROUP BY PRODUCT_TYPE
        ORDER BY COUNT(*) DESC;
    

    我的建议是,您按概念分组(在本例中为 PRODUCT_TYPE),然后按出现次数 count(*) 进行排序。上面的查询会做你想做的事。 子查询主要用于排序或排除不感兴趣的行。

    你看到的 MIN 并不完全是一个 MIN,它是一个事件,你想首先看到出现次数较少的那个(我猜这意味着出现的次数更少)。

    干杯,

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-14
      • 2010-10-12
      • 1970-01-01
      • 2021-07-15
      • 1970-01-01
      • 1970-01-01
      • 2018-02-25
      • 1970-01-01
      相关资源
      最近更新 更多