【问题标题】:Get a field from a table when using MAX function使用 MAX 函数时从表中获取字段
【发布时间】:2015-11-03 12:03:33
【问题描述】:

我有以下运行良好的 MySQL 语句。

SELECT c.id, IFNULL(MAX(l.id), 0) as level_id
FROM course c
LEFT JOIN level l ON c.level_id = l.id
WHERE c.user_id = '123'    
GROUP BY c.id

一门课程可以有多个级别,因此IFNULL(MAX(l.id), 0) 通过选择最高级别来工作。

但是,我不想返回最高级别的 id,而是想获取名称。我尝试了以下方法,但 MySQL 不喜欢在选择中使用值加入。

SELECT c.id, IFNULL(MAX(l.id), 0) as level_id, l2.name
FROM course c
LEFT JOIN level l ON c.level_id = l.id 
INNER JOIN level l2 ON level_id = l2.id
WHERE c.user_id = '123'     
GROUP BY c.id

我已经简化了我在问题中的陈述(为了便于阅读),所以希望这个问题仍然有意义。

【问题讨论】:

  • 第一个查询应该给您一个错误,因为您在 JOIN 中间有一个 WHERE 子句(代码看起来与您的第二个查询相同)。
  • @Kickstart 感谢您的发现,更新了我的问题

标签: mysql group-by max


【解决方案1】:

对于这种类型的查询,我认为最简单的方法是substring_index()/group_concat()技巧:

SELECT c.id, COALESCE(MAX(l.id), 0) as level_id,
       SUBSTRING_INDEX(GROUP_CONCAT(l2.name ORDER BY l.id DESC), ',', 1) as name
FROM course c LEFT JOIN
     level l
     ON c.level_id = l.id INNER JOIN
     level l2
     ON level_id = l2.id
WHERE c.user_id = '123'
GROUP BY c.id;

请注意,WHERE 在您的查询中放错了位置。

关于这种方法的注意事项:

  • 如果name 可能有逗号,则需要使用不同的分隔符。
  • group_concat() 中间结果的长度存在内部限制。如果这是一个问题,可以增加长度。

【讨论】:

  • 我确实想知道是否需要第二次加入到级别表(如果有一个 ID 为 0 的虚拟级别)。但是认为连接条件无论如何都会遇到困难,因为我认为使用聚合函数的结果是有意义的(即,处理 0 的 l.id)
【解决方案2】:

另一种方法是进行子查询并将结果与​​级别表连接起来以获取级别名称:-

SELECT sub0.id, sub0.level_id, l2.name
FROM
(
    SELECT c.id, IFNULL(MAX(l.id), 0) as level_id
    FROM course c
    LEFT JOIN level l ON c.level_id = l.id 
    WHERE c.user_id = '123'
    GROUP BY c.id
)
LEFT OUTER JOIN level l2 ON l2.id = sub0.level_id

【讨论】:

    猜你喜欢
    • 2022-11-21
    • 2011-10-27
    • 2017-05-10
    • 2012-02-02
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    相关资源
    最近更新 更多