访问查询:在每个类别中查找最高级别的产品

时间:2011-03-29 10:29:28

标签: sql ms-access

我有一个查询计算每个类别的产品排名:

qryEvalProd    
category Product   Rank
-------- -------   ----
Cat1     Prod6     1254
Cat1     Prod1      950
Cat1     Prod2      800
Cat2     Prod3     1500
Cat2     Prod5      950

我想对此进行查询,以返回每个类别的最佳产品:

category Product   
-------- -------   
Cat1     Prod6     
Cat2     Prod3    

我知道我可以使用包含group by和Max的相关子查询来做到这一点,但是出于性能原因,我试图使用Group By和First一次性完成它。但是我无法表达我希望按DESC Rank排序的每只猫的First Prod的事实。

有没有办法一次性完成?

4 个答案:

答案 0 :(得分:1)

此调整可让您添加所需的ORDER。它使用子查询...但不是相关的子查询,因此性能不会受到影响:

SELECT Category, First(Product) AS BestProduct
FROM (
  SELECT Category, Product, Rank
  FROM qryEvalProd
  ORDER BY Category, Rank DESC
) AS Ordered
GROUP BY Category;

答案 1 :(得分:0)

也许使用HAVING clause可能有帮助吗?

答案 2 :(得分:0)

事实上这似乎有效。我只是有点生气,因为我不能在我的陈述中强制输入数据集的顺序,但无论如何,它更糟糕..

SELECT Category, First(Product) AS BestProduct
FROM qryEvalProd    
GROUP BY Category;

我可以添加ORDER BY Category而不会对输出产生任何影响。我本来希望添加ORDER BY Category, Rank,但这是不被接受的。

如果有人有更好的建议,你仍然可以接受。

答案 3 :(得分:0)

你可能会从这样的事情开始:

SELECT Category, Product
FROM qryEvalProd
WHERE Product = 
    (SELECT TOP 1 Self.Product 
    FROM qryEvalProd AS Self
    WHERE Self.Category = qryEvalProd.Category
    ORDER BY Self.Rank DESC)

如果存在关联的可能性(即,同一类别中具有相同排名的两个产品),此查询将任意选择其中一个。

如果您希望它始终选择相同的一个,您可以通过更改ORDER BY子句使其成为您想要的。例如,如果出现平局,您希望它按字母顺序选择具有第一个Product值的那个,您可以将ORDER BY子句更改为:

ORDER BY Self.Rank DESC, Self.Product

如果您希望它列出所有排名最高的产品,您可以使用如下查询:

SELECT Category, Product
FROM qryEvalProd
WHERE Rank = 
    (SELECT Max(Self.Rank) 
    FROM qryEvalProd AS Self
    WHERE Self.Category = qryEvalProd.Category)