我可以使用group by的非聚合列吗?

问题描述:

您不能(不应该)将非集合放在GROUP BY查询的SELECT行中。我可以使用group by的非聚合列吗?

我想要访问与最大值相关的非聚合之一。用简单的英语,我想要一张每张最古老的ID的表格。

CREATE TABLE stuff (
    id int, 
    kind int, 
    age int 
); 

该查询给我之后,我的信息:

SELECT kind, MAX(age) 
FROM stuff 
GROUP BY kind; 

但它不是在最有用的形式。我真的希望id与每一行相关联,所以我可以在以后的查询中使用它。

我正在寻找这样的事情:

SELECT id, kind, MAX(age) 
FROM stuff 
GROUP BY kind; 

输出这样的:

SELECT stuff.* 
FROM 
    stuff, 
    (SELECT kind, MAX(age) 
    FROM stuff 
    GROUP BY kind) maxes 
WHERE 
    stuff.kind = maxes.kind AND 
    stuff.age = maxes.age 

这真的好像应该在客场得到这个信息,而无需加入。我只需要SQL引擎在计算最大值时记住其他列。

+1

敢肯定你会需要加入以获得你想要的。如果有某种方式可以说“从这一行中拉出数值,你只是从最大值开始”,但如果没有加入,我就不知道了。 – heisenberg 2010-07-02 18:07:14

+2

尽管最大年龄可能不会只有一个ID。哪一个应该被退回?或者你应该每行一个? – Blorgbeard 2010-07-02 18:11:50

+0

或者你有多个集合选择不同的行的情况下,需要某种语法糖,让你告诉它每个字段需要关联的集合。 – heisenberg 2010-07-02 18:13:32

你不能得到MAX找到的行的Id,因为可能不会有最大年龄的一个id。

您必须有一个连接,因为聚合函数max会检索许多行并选择最大值。 所以你需要一个连接来选择一个聚合函数找到的连接。

换句话说,如果用sum代替max,你会如何预期查询的行为?

尽管内连接可能比您的子查询更高效。

您不能(不应该)将非聚合放在GROUP BY查询的SELECT行中。

您可以并必须定义您正在按照聚合函数进行分组以返回正确的结果。 MySQL(和SQLite)以他们的无限智慧决定违背规范,并允许查询接受SELECT中引用的GROUP BY子句缺失的列 - 它有效地使这些查询不可移植。

真的好像应该离开去获取这些信息而不需要加入。

如果不能访问MySQL不支持的分析/排名/窗口函数,自加入派生表/内联视图是获取所需结果的最便捷方式。

+0

您写道:“您可以并且必须定义您正在按照聚合函数分组,以返回正确的结果。”这听起来像你正在响应@deft_code所要求的内容。他在谈论定义GROUP BY的情况,但是*没有聚合*。 – Quuxplusone 2013-07-09 23:39:41

我认为确实要求系统一次性解决问题,而不是必须两次完成工作(找到最大值,并找到相应的ID)是很诱人的。您可以使用CONCAT(如建议在Naktibalda refered条),不知道这样会比较effeciant

SELECT MAX(CONCAT(LPAD(age, 10, '0'), '-', id) 
FROM STUFF1 
GROUP BY kind; 

应该做的工作,你有分裂的答案,得到的年龄和ID。 (这真的很难看)

+0

' - '是在年龄和id之间添加分隔符,而不是减法 – mb14 2010-07-02 19:48:37

在最近的数据库,你可以(通过...分区之前)使用了SUM()来解决这个问题:

select id, kind, age as max_age from (
    select id, kind, age, max(age) over (partition by kind) as mage 
    from table) 
where age = mage 

然后可将单次