SQL min(),max()

时间:2017-10-31 16:45:44

标签: sql sql-server adventureworks

我有一张包含产品价格历史的表格(ProductCostHistory)。 列:ProductID(PK,FK),StartDate(PK),EndDate,StandardCost,ModifiedDate

这就是表格的样子:

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

由于

4 个答案:

答案 0 :(得分:1)

这是一种方式...选择当前记录,然后加入产品ID的最小/最大子查询。

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

答案 1 :(得分:1)

考虑为 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

答案 2 :(得分:0)

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

您是否需要所需输出的第二列?如果你采取平均值,我可以理解它的用途,但在目前的例子中,我认为包含它并不合理吗?

这应该有效:

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

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

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

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(通用表格式)来获取所需的聚合(MIN和MAX价格),我喜欢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;

答案 3 :(得分:0)

如果在查询的选择部分中包含standardcost,它将返回所有条目。

我认为以下查询应该适合您

SELECT productid,MAX(StandardCost),MIN(StandardCost)FROM ProductCostHistory GROUP BY productid