按列分组并依赖于另一列的内容

4
这里有一个我正在尝试通过MySQL查询来清晰解决的问题的简化版本。这不是我正在处理的实际表。 如果我有以下表格:
Name Buyer ID  
John Fred  4  
John Smith 3  
Fred Sally 2  
John Kelly 1

我需要一个查询,返回以下结果:
Name Buyer ID      
John Fred  4  
Fred Sally 2  

我们需要按照“名称”分组,并显示最新的行/买家/ID。
我尝试通过执行嵌套的SELECT语句来实现这一点,在其中我首先执行了“ORDER BY ID DESC”,然后在最外层的SELECT中执行了“GROUP BY NAME”。虽然这是解决问题的一种迂回方式,但似乎由于排序的特性,正确的选择会被返回给我。不幸的是,“GROUP BY”不能“保证”“买家”列将包含预期的条目。
有什么有用的建议可以实现这个查询吗?目前,我在一个大表转储上运行了一个高度低效的PHP版本的查询 - 绝对不是最好的选择。

+1 提供示例数据和预期结果。 - John Woo
2个回答

4

尝试这个,子查询的背后思想是使用 MAX(聚合函数)为每个 Name 获取最新的 ID。然后在子查询的两列上将其与表本身连接。

SELECT  a.*
FROM    tableName a
        INNER JOIN 
        (
            SELECT name, MAX(ID) maxID
            FROM tableName
            GROUP BY name
        ) b ON a.Name = b.Name AND
                a.ID = b.MaxID

我最终通过修复我的查询问题(类似于duellsy的示例)解决了它,但我将不得不尝试一下这个。这比子查询执行得更好吗? - SDM
这个查询的关键是它可以在所有关系型数据库管理系统上运行。尝试在MSSQL上运行您接受的查询语句,如果能够正常执行就说明没有问题。此外,对字段进行索引还会对查询的性能产生巨大影响。 :D - John Woo
啊,我发现了两者之间有趣的差异 - http://sqlfiddle.com/#!2/1d483/2 和 http://sqlfiddle.com/#!2/1d483/1 - 它们处理重复项的方式似乎不同。你查询中的 'GROUP BY' 不应该防止这种情况发生吗? - SDM
DISTINCT可以解决这个问题 http://sqlfiddle.com/#!2/1d483/3 不管怎样,这取决于你:D 你没有提到你的表中可能存在重复行的可能性。 - John Woo
你现在看到区别了吗? :D - John Woo
显示剩余2条评论

1

另一种选择是在子查询中加载排序后的数据,然后对结果进行分组。我无法引用这个说法,但我在几个地方读到过这个说法,这样做不会对性能造成(可察觉的)影响。

因此,可以尝试以下方式:

SELECT * 
FROM (
    SELECT * 
    FROM `yourtable` 
    ORDER BY `id` DESC
) as `tmp` 
GROUP BY `name`

FYI,找到了一个关于子查询性能的参考资料:https://dev59.com/pHRC5IYBdhLWcg3wROtQ#356699 - duellsy
这就是我使用的内容 - 结果发现我的一个列存在问题,导致排序不正确。我很高兴没有出现显著的性能损失。 :) - SDM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接