SQL 最小值(),最大值()

SQL min(), max()

我有一个 table,其中包含产品价格历史记录 (ProductCostHistory)。 列:ProductID(PK,FK)、StartDate(PK)、EndDate、StandardCost、ModifiedDate

这就是 table 的样子:

ProductID   StartDate   EndDate     StandardCost    ModifiedDate
707         2011-05-31  2012-05-29  12,0278        2012-05-29
707         2012-05-30  2013-05-29  13,8782        2013-05-29
707         2013-05-30      NULL    13,0863        2013-05-16
708         2011-05-31  2012-05-29  12,0278        2012-05-29 
708         2012-05-30  2013-05-29  13,8782        2013-05-29
708         2013-05-30  NULL        13,0863        2013-05-16

对于我要查看的每个产品:当前价格、历史最高价和最低价。

这是我的代码:

USE AdventureWorks2014
GO
SELECT Distinct ProductCostHistory.ProductID, ProductCostHistory.StandardCost, MAX(ProductCostHistory.StandardCost) AS HighestPrice, MIN(ProductCostHistory.StandardCost) AS LowestPrice FROM Production.ProductCostHistory
GROUP BY ProductID, StandardCost
Order by ProductID

输出如下所示:

ProductID   StandardCost    HighestPrice    LowestPrice
707         12,0278         12,0278         12,0278
707         13,0863         13,0863         13,0863
707         13,8782         13,8782         13,8782
708         12,0278         12,0278         12,0278
708         13,0863         13,0863         13,0863
708         13,8782         13,8782         13,8782

但我更希望它像这样(示例):

PRoductID    StandardCost    HighestPrice     LowestPrice
707          13,0863         13,8787          12,0278
708          12,0278         13,8782          12,0278

谢谢

您的问题是 Product.StandardCost 在聚合函数之外。

您是否需要您请求的所需输出中的第 2 列?如果您取平均值,我可以理解它的用处,但在当前示例中,我认为包含它没有意义?

这应该有效:

USE AdventureWorks2014
GO
SELECT ProductCostHistory.ProductID, MAX(ProductCostHistory.StandardCost) AS HighestPrice, MIN(ProductCostHistory.StandardCost) AS LowestPrice 
FROM Production.ProductCostHistory
GROUP BY ProductID
Order by ProductID

************ 编辑 ************

根据您提供的有关开始的更多信息table,以下内容将满足您的要求:

WITH CTE_AggregatePrices AS
(
  SELECT ProductID
    ,  MAX(StandardCost) AS HighestPrice
    ,  MIN(StandardCost) AS LowestPrice 
  FROM ProductCostHistory
  GROUP BY ProductID
)
SELECT PCH.ProductID
    ,  PCH.StandardCost
    ,  CAP.HighestPrice
    ,  CAP.LowestPrice
FROM ProductCostHistory AS PCH
INNER JOIN CTE_AggregatePrices AS CAP ON PCH.ProductID = CAP.ProductID
WHERE PCH.EndDate IS NULL;

好的,所以我所做的是使用 CTE(通用 Table 表达式)来获取您需要的聚合(最低和最高价格),我喜欢 CTE,因为它们简单易读,但它们并不总是最好的前进方式,但在这种情况下它非常符合要求。

因此,对于每个 ProductID 的 MIN 和 MAX 数字,这只是获取当前价格的一种情况,根据您的数据示例,这是一个简单的 WHERE 子句,用于检查是否EndDate 为 NULL。我们通过 ProductID 将此结果加入聚合 CTE,这使我们能够显示产品的最高和最低价格的当前价格。

由于这是一项作业,请花点时间检查一下这是否是要求您完成的,并且您是否了解正在发生的事情。例如,如果您的课程尚未涵盖 CTE,但我非常怀疑他们正在寻找这个答案,即使它是有效的。您可以使用子查询获得相同的结果:

SELECT PCH.ProductID
    ,  PCH.StandardCost
    ,  CAP.HighestPrice
    ,  CAP.LowestPrice
FROM ProductCostHistory AS PCH
INNER JOIN 
(
  SELECT ProductID
    ,  MAX(StandardCost) AS HighestPrice
    ,  MIN(StandardCost) AS LowestPrice 
  FROM ProductCostHistory
  GROUP BY ProductID
) AS CAP ON PCH.ProductID = CAP.ProductID
WHERE PCH.EndDate IS NULL;

如果您在查询的 select 部分中包含标准成本,它将 return 所有条目。

我认为下面的查询应该适合你

SELECT productid , MAX(StandardCost) , MIN(StandardCost) FROM ProductCostHistory 按产品编号分组

这是一种方法...select 当前记录,然后加入产品 ID 的 min/max 子查询。

select p.ProductID, p.StandardCost, g.MaxPrice, g.MinPrice
from ProductCostHistory p
inner join (select ProductID, MAX(StandardCost) as MaxPrice, MIN(StandardCost) as MinPrice
            from ProductCostHistory group by ProductID) g
  on g.ProductID = p.ProductID
where p.StartDate <= GETDATE() AND (p.EndDate > GETDATE() OR p.EndDate IS NULL)

SQL Fiddle

考虑对 CurrentPrice:

使用条件聚合
SELECT h.ProductID, 
       MAX(CASE WHEN h.EndDate IS NULL THEN h.StandardCost END) AS CurrentPrice,
       MAX(h.StandardCost) AS HighestPrice, 
       MIN(h.StandardCost) AS LowestPrice 
FROM Production.ProductCostHistory h
GROUP BY h.ProductID
ORDER BY h.ProductID