新手寻求帮助,Max Aggregate未返回预期结果

时间:2018-09-10 13:31:02

标签: sql sql-server tsql

我对MS-SQL还是很陌生。我有一个简单的表和查询,可以满足我的所有需求。我知道这将是我所忽略的根本。

我已经更改了字段名称,但是想法是一样的。 因此,我们的想法是,每次有人注册时,他们都会获得一个RegID,姓名和团队。名称是唯一的,因此下面的约翰更改了团队。那是我的麻烦。

            Football Table
+------------+----------+---------+
| Max_RegID  |   Name   |   Team  |
+------------+----------+---------+
|   100      |   John   |   Red   |
|   101      |   Bill   |   Blue  |
|   102      |   Tom    |   Green |
|   103      |   John   |   Green |
+------------+----------+---------+

在底部使用Max_RegID进行查询时,我希望只返回一条记录。

+------------+----------+---------+
| Max_RegID  |   Name   |   Team  |
+------------+----------+---------+
|   103      |   John   |   Green |
+------------+----------+---------+

相反,我回到下面,其中似乎包括Max_RegID,但也包括每个团队。我在做什么错了?

+------------+----------+---------+
| Max_RegID  |   Name   |   Team  |
+------------+----------+---------+
|   100      |   John   |   Red   |
|   103      |   John   |   Green |
+------------+----------+---------+

我的查询

SELECT
  Max(Football.RegID) AS Max_RegID,
  Football.Name,
  Football.Team
FROM
  Football    
GROUP BY
  Football.RegID,
  Football.Name,
  Football.Team

编辑*删除了WHERE语句

4 个答案:

答案 0 :(得分:1)

获得结果的原因是因为GROUP BY子句的结构方式。

当您使用任何聚合函数MAX(X)SUM(X)COUNT(X)或您拥有的函数时,您是在告诉SQL引擎您想要column的聚合值GROUP BY子句中列出的列的每个唯一组合的X。

在编写的查询中,您将按表中的所有三列进行分组,从而告诉SQL引擎每个元组都是唯一的。因此,查询将返回所有值,而实际上您根本没有得到任何MAX

结果中您真正想要的是Name列中每个不同值的最大RegID,以及与此相随的Team,{{1 })组合。

要完成此操作,您需要在初始数据集中为每个RegID找到一个Name,然后使用该MAX(ID)列表为{{1}添加值}和Name放在辅助数据集中。

注意事项(来自@HABO的注释):前提是RegID是唯一数字(RegID列,Name中的值或这种东西)。如果存在重复的值,则将失败。

最直接的方法是使用子查询。下面的子查询获取唯一的Team,然后联接到原始表以添加其他值。

IDENTITY

编辑:对不起。我只是重新阅读了问题。要仅获取SEQUENCE的单个记录,只需将RegID从子查询中取出,您将只获得当前的最大值,可用于在最大值中找到值。其余的列。

SELECT
  f.RegID
 ,f.Name
 ,f.Team
FROM
  Football AS f
  JOIN
    (--The sub-query, sq, gets the list of IDs
      SELECT
        MAX(f2.RegID) AS Max_RegID
      FROM
        Football AS f2
      GROUP BY
        f2.Name
    ) AS sq
      ON
      sq.Max_RegID = f.RegID;

答案 1 :(得分:0)

使用row_number()

    select * from 
(SELECT
      Football.RegID AS Max_RegID,
      Football.Name,
      Football.Team, row_number() over(partition by name order by Football.RegID desc) as rn
    FROM
      Football
    WHERE
      Football.Name = 'John')a
where rn=1

答案 2 :(得分:0)

您需要self加入:

select f1.*
from Football f inner join
     Football f1 
     on f1.name = f.name
where f.Max_RegID = 103;

重新访问问题后,样本数据将提示我子查询:

select f.*
from Football f
where name = (select top (1) f1.name
              from Football f1
              order by f1.Max_RegID desc
             );

答案 3 :(得分:0)

您只需按照以下方式编辑查询

SELECT *      
FROM
  Football f
WHERE
  f.Name = 'John' and 
 Max_RegID = (SELECT  Max(Football.Max_RegID) where Football.Name = 'John'
         )

或 如果sql server只是使用此

select top 1 * from Football f
where f.Name = 'John'
order by Max_RegID desc

或 如果是mysql,那么

select  * from Football f
    where f.Name = 'John'
    order by Max_RegID desc
Limit 1