MySQL MIN / MAX返回正确的值,但不返回相关的记录信息

时间:2011-02-22 00:08:51

标签: mysql aggregate-functions max

我真的被困在这上面了。我显然不了解MIN / MAX概念。

我正在尝试从一组work_type和work_id获取最新一行。

如果我从MIN更改为MAX,它会更改返回的时间戳,但它永远不会从该记录中提取状态信息。

示例:

"SELECT 
    CONCAT(work_type, work_id) AS condition_id, 
    status,
    MIN(created_timestamp) as latest
  FROM conditions
  GROUP BY condition_id"

有了MIN,我得到了:

    Array
    (
        [0] => Array
            (
                [condition_id] => cutouts00002
                [status] => bad
                [latest] => 2011-02-21 15:20:27
            )

        [1] => Array
            (
                [condition_id] => paintings00002
                [status] => damagez
                [latest] => 2011-02-21 14:43:35
            )

    )

使用MAX我得到:

Array
(
    [0] => Array
        (
            [condition_id] => cutouts00002
            [status] => bad
            [latest] => 2011-02-21 15:22:20
        )

    [1] => Array
        (
            [condition_id] => paintings00002
            [status] => damagez
            [latest] => 2011-02-21 14:43:41
        )

)

事情是,具有最新时间戳的行中的状态是“无损坏”,但它永远不会返回与MAX(current_timestamp)对应的行,它只会返回“damagez”行。

感谢任何帮助。

感谢。

3 个答案:

答案 0 :(得分:2)

您已经成为MySQL宽松规则的牺牲品,允许非聚合包含在GROUP BY查询中。当然,您使用MIN或MAX,一次只能 ONE ,但请考虑以下问题:

SELECT 
    CONCAT(work_type, work_id) AS condition_id, 
    status,
    MIN(created_timestamp) as earliest,
    MAX(created_timestamp) as latest
  FROM conditions
  GROUP BY condition_id

现在,请考虑状态列应该来自哪一行。在聚合(GROUP BY中的聚合)和非聚合列之间建立相关性是荒谬的。

相反,请像这样编写您的查询

SELECT X.condition_id, C.status, X.earliest
FROM (
  SELECT 
    CONCAT(work_type, work_id) AS condition_id, 
    status,
    MIN(created_timestamp) as earliest
  FROM conditions
  GROUP BY condition_id
) X JOIN conditions C
  on CONCAT(c.work_type, c.work_id) = X.condition_id
  and c.created_timestamp = X.earliest

但是如果你有两个具有相同created_timestamp的记录,那就会变得更加棘手

SELECT X.condition_id, Max(C.status) status, X.earliest
FROM (
  SELECT 
    CONCAT(work_type, work_id) AS condition_id, 
    status,
    MIN(created_timestamp) as earliest
  FROM conditions
  GROUP BY condition_id
) X JOIN conditions C
  on CONCAT(c.work_type, c.work_id) = X.condition_id
  and c.created_timestamp = X.earliest
GROUP BY X.condition_id, X.earliest

答案 1 :(得分:0)

我一般不得不做一些非常狡猾的事情。

我的解决方案是T-SQL,但我希望你能重做它。

SELECT 
    CONCAT(c.work_type, c.work_id) as condition_id, 
    c.status, 
    c.created_timestamp as latest
FROM conditions c
JOIN (SELECT work_type, work_id, max(current_timestamp) as latest GROUP BY work_type, work_id) c2 
    ON c.work_type = c2.work_type
    AND c.work_id = c2.work_id
    AND c.created_timestampe = c2.latest

答案 2 :(得分:0)

我更希望将子查询放在WHERE子句中,因为它更容易阅读。

SELECT 
    CONCAT(work_type, work_id) AS condition_id, 
    status,
    created_timestamp as latest
FROM
    conditions
WHERE
    created_timestamp = (
        SELECT
            MIN(conditions2.created_timestamp)
        FROM
            conditions AS conditions2
        WHERE
            conditions2.condition_id = conditions.condition_id
    )
GROUP BY
    condition_id

此外,如果第一个查询要有任何其他连接或where子句,则可以在子查询中重复这些连接。

SELECT 
    CONCAT(work_type, work_id) AS condition_id, 
    status,
    created_timestamp as latest
FROM
    conditions
    INNER JOIN some_table on condition.id = some_table.condition_id
WHERE
    some_table.some_column > 50 AND 
    created_timestamp = (
        SELECT
            MIN(conditions2.created_timestamp)
        FROM
            conditions AS conditions2
            INNER JOIN some_table AS some_table2 on condition2.id = some_table2.condition_id
        WHERE
            some_table.some_column > 50 AND 
            conditions2.condition_id = conditions.condition_id
    )
GROUP BY
    condition_id