使用GROUP BY选择多个(非聚合函数)列

时间:2013-07-01 18:26:11

标签: sql ms-access greatest-n-per-group

我尝试从一列中选择最大值,同时按另一个具有多个重复值的非唯一ID列进行分组。原始数据库看起来像:

mukey    | comppct_r | name | type
65789    | 20        | a    | 7n
65789    | 15        | b    | 8m
65789    | 1         | c    | 1o
65790    | 10        | a    | 7n
65790    | 26        | b    | 8m
65790    | 5         | c    | 1o
...

这可以正常使用:

SELECT c.mukey, Max(c.comppct_r) AS ComponentPercent
FROM c
GROUP BY c.mukey;

返回如下表格:

mukey    | ComponentPercent
65789    | 20
65790    | 26
65791    | 50
65792    | 90

我希望能够在不影响GROUP BY功能的情况下添加其他列,将名称和类型等列包含在输出表中,如:

mukey    | comppct_r | name | type
65789    | 20        | a    | 7n
65790    | 26        | b    | 8m
65791    | 50        | c    | 7n
65792    | 90        | d    | 7n

但它总是输出一个错误,说我需要使用带select语句的聚合函数。我应该怎么做呢?

5 个答案:

答案 0 :(得分:21)

你自己遇到问题。这是可能的解决方案之一:

select c.mukey, c.comppct_r, c.name, c.type
from c yt
inner join(
    select c.mukey, max(c.comppct_r) comppct_r
    from c
    group by c.mukey
) ss on c.mukey = ss.mukey and c.comppct_r= ss.comppct_r

另一种可能的方法,相同的输出:

select c1.*
from c c1
left outer join c c2
on (c1.mukey = c2.mukey and c1.comppct_r < c2.comppct_r)
where c2.mukey is null;

这里有关于这个主题的全面和解释性答案:SQL Select only rows with Max Value on a Column

答案 1 :(得分:1)

任何非聚合列都应该在Group By子句中。为什么??

                  t1
x1           y1           z1
1            2             5
2            2             7

现在您正在尝试编写如下查询:

select x1,y1,max(z1) from t1 group by y1;

现在这个查询只会产生一行,但x1的值应该是多少?这基本上是一种未定义的行为。为了解决这个问题,SQL会将此查询错误。

现在,您可以为x1选择聚合函数,也可以将x1添加到group by。请注意,这一切都取决于您的要求。

如果您希望所有在z1分组上具有聚合的行按y1分组,则可以使用SubQ方法。

Select x1,y1,(select max(z1) from t1  where tt.y1=y1 group by y1)
 from t1 tt;

这将产生如下结果:

                  t1
x1           y1           max(z1)
1            2             7
2            2             7

答案 2 :(得分:0)

尝试使用虚拟表,如下所示:

SELECT vt.*,c.name FROM(
SELECT c.mukey, Max(c.comppct_r) AS ComponentPercent
FROM c
GROUP BY c.muke;
) as VT, c 
WHERE VT.mukey = c.mukey 

答案 3 :(得分:0)

您不能只添加其他列而不将其添加到GROUP BY或应用聚合函数。原因是,一列内的列值可能不同。例如,您可以有两行:

mukey    | comppct_r | name | type
65789    | 20        | a    | 7n
65789    | 20        | b    | 9f

如果列nametype的聚合组应该如何?

如果组内的名称和类型始终相同,只需将其添加到GROUP BY子句中:

SELECT c.mukey, Max(c.comppct_r) AS ComponentPercent
FROM c
GROUP BY c.muke, c.name, c.type;

答案 4 :(得分:0)

使用“拥有”子句

SELECT *
FROM c
GROUP BY c.mukey
HAVING c.comppct_r = Max(c.comppct_r);