繁体   English   中英

使用max和其他SQL聚合函数

[英]Using max and other SQL aggregate functions

每当我使用SQL聚合函数时,都会发现它们的实用程序因需要Group By子句而受阻。 我总是最终不得不使用一堆嵌套的选择来得到我想要的东西。 我想知道我是否只是没有正确使用这些功能。

例如。 如果我有以下数据:

ID     Fruit     Color     CreatedDate
--     -----     -----     -----------
1      Apple      Red      2014-07-25 12:41:44.000
2      Apple      Green    2014-07-31 10:01:01.000
3      Apple      Blue     2014-07-10 07:05:51.317
4      Orange     Orange   2014-06-26 13:42:35.360

我想获取最近创建的苹果记录。 如果我使用这个:

SELECT [ID]
      ,[Fruit]
      ,[Color]
      ,max([CreatedDate])
  FROM [CCM].[dbo].[tblFruit]
  WHERE Fruit = 'Apple'
  GROUP BY ID, Fruit, Color

它给了我所有三个Apple条目,而不仅仅是最新条目,因为我被迫在group by子句中包括所有其他列。 真的,我只是希望它按成果分组,并给我最新的记录(整个记录,而不仅仅是列的子集)。

为了得到我想要的东西,我必须使用这个:

SELECT [ID]
      ,[Fruit]
      ,[Color]
      ,[CreatedDate]
  FROM [CCM].[dbo].[tblFruit]
  WHERE Fruit = 'Apple' AND CreatedDate IN
  (SELECT max([CreatedDate]) as [CreatedDate]
  FROM [CCM].[dbo].[tblFruit]
  WHERE Fruit = 'Apple')

这对我来说很丑陋,而忘记了SQL中的聚合并在.NET中进行任何最小值,最大值,计数等操作,会更容易。

这是使用聚合(带有嵌套选择)的正确方法还是我做错了?

对于这种情况,最好使用像row_number()这样的窗口函数

select id, fruit, color, createddate
from 
(
  select id, fruit, color, createddate,
    row_number() over(partition by fruit order by createddate desc) seq
  from tblFruit
) d
where seq = 1;

观看演示

使用此功能,您可以按fruit对数据进行分区, createddate每个fruit的行进行createddate 通过将row_number()放在子查询中,您将返回每个fruit的第一行-这些是seq=1的项目。 如果您只寻找Apple ,则可以轻松添加WHERE子句。

您还可以通过使用子查询为每个fruit选择max(createddate)来获得fruit

select f.id,
  f.fruit,
  f.color,
  f.createddate
from tblFruit f
inner join
(
  select fruit, max(createddate) CreatedDate
  from tblfruit
  group by fruit
) d
  on f.fruit = d.fruit
  and f.createddate = d.createddate;

参见演示 您得到相同的结果,仍然可以对此应用WHERE过滤器。

根据您的评论,您可以使用CTE为每个水果建立最大日期列表。 然后,您可以将其重新连接到原始表,以获得与该最大日期匹配的完整行。

SQL小提琴

  with MaxDates as (select fruit, max(createddate) as maxdate from table1 group by fruit) select t1.* from table1 t1 inner join maxdates md on t1.fruit = md.fruit and t1.createddate = md.maxdate 

顺便说一句,您真的不想尝试将这种功能推入您的应用程序。 在SQL中做这种事情绝对更好。 如果没有其他问题,请考虑表中是否有数百万行。 您当然不希望将数据库中的那几百万行推到应用程序中,以将其总计为一行,依此类推。

如何将TOP与ORDER BY一起使用

SELECT TOP(1) *
  FROM [CCM].[dbo].[tblFruit]
  WHERE Fruit = 'Apple'
  ORDER BY [CreatedDate] DESC

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM