Sql Server:如何在WHERE子句中使用像MAX这样的聚合函数?

33

我想获得这条记录的最大值,请帮助我:

SELECT rest.field1 
    FROM mastertable AS m
    INNER JOIN  (
        SELECT t1.field1 field1, 
               t2.field2
            FROM table1 AS T1 
            INNER JOIN table2 AS t2 ON t2.field = t1.field 
            WHERE t1.field3=MAX(t1.field3)
        --                  ^^^^^^^^^^^^^^  Help me here.
    ) AS rest ON rest.field1 = m.field

1
我不是SQL大师,但那个是否有效呢?你甚至没有说明你遇到了什么问题,以及你发布的解决方案是否有效。 - Nick Bedford
你需要更好地解释你想要什么,这样我才能理解这个问题。 - tster
有没有办法得到正确的结果? - Geetha
6个回答

45

正如您已经注意到的那样,WHERE子句不允许在其中使用聚合函数。这就是HAVING子句的用途。

HAVING t1.field3=MAX(t1.field3)

3
顺便提一下(5年后),HAVING子句实际上是用于与分组元素一起使用的。然而,在大多数SQL引擎中,即使没有GROUP BY子句,它也可以与聚合子句(MINMAXAVG)一起使用。 - Powerlord

36

你可以使用子查询...

WHERE t1.field3 = (SELECT MAX(st1.field3) FROM table1 AS st1)

但是我实际上会将这个条件从 where 子句移到 join 语句中,作为 ON 子句的 AND 条件。


子查询是实现您想要的唯一可能的方式。 - Oliver Hanappi

14

使用HAVING子句中max函数的正确方式是先进行自连接:

select t1.a, t1.b, t1.c
from table1 t1
join table1 t1_max
  on t1.id = t1_max.id
group by t1.a, t1.b, t1.c
having t1.date = max(t1_max.date)
以下是如何与子查询联接的示例:
select t1.a, t1.b, t1.c
from table1 t1
where t1.date = (select max(t1_max.date)
                 from table1 t1_max
                 where t1.id = t1_max.id)

在处理多表联接时,请确保创建单个数据集后再使用聚合函数:

select t1.id, t1.date, t1.a, t1.b, t1.c
into #dataset
from table1 t1
join table2 t2
  on t1.id = t2.id
join table2 t3
  on t1.id = t3.id


select a, b, c
from #dataset d
join #dataset d_max
  on d.id = d_max.id
having d.date = max(d_max.date)
group by a, b, c

子查询版本:

select t1.id, t1.date, t1.a, t1.b, t1.c
into #dataset
from table1 t1
join table2 t2
  on t1.id = t2.id
join table2 t3
  on t1.id = t3.id


select a, b, c
from #dataset d
where d.date = (select max(d_max.date)
                from #dataset d_max
                where d.id = d_max.id)

5
SELECT rest.field1
FROM mastertable as m
INNER JOIN table1 at t1 on t1.field1 = m.field
INNER JOIN table2 at t2 on t2.field = t1.field
WHERE t1.field3 = (SELECT MAX(field3) FROM table1)

1

但是在查询构建器中仍然出现错误消息。我正在使用 SqlServerCe 2008。

SELECT         Products_Master.ProductName, Order_Products.Quantity, Order_Details.TotalTax, Order_Products.Cost, Order_Details.Discount, 
                     Order_Details.TotalPrice
FROM           Order_Products INNER JOIN
                     Order_Details ON Order_Details.OrderID = Order_Products.OrderID INNER JOIN
                     Products_Master ON Products_Master.ProductCode = Order_Products.ProductCode
HAVING        (Order_Details.OrderID = (SELECT MAX(OrderID) AS Expr1 FROM Order_Details AS mx1))

我按照@powerlord所说,将WHERE替换为HAVING。但仍显示错误。
解析查询时出错。[标记行号=1,标记行偏移量=371,错误的标记=SELECT]

我认为你可以简化这里的HAVING子句,只需将其改为HAVING Order_Details.OrderID = MAX(Order_Details.OrderID) - Powerlord

1

是的,你需要在Group by子句之后使用Having子句, 因为where子句只能用于简单参数的数据筛选, 但是,Group by和Having语句的组合可以根据某些聚合函数对数据进行分组和过滤。


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