SQl - 根据数量选择最优价格

时间:2015-12-09 22:28:02

标签: sql sql-server

我有一张表格,其中包含特定商品的价格,具体取决于订购数量和下订单的客户类型......

ID    Name     Quantity     ClientType    Price/Unit ($)
========================================================
1     Cheese      10        Consumer      20
2     Cheese      20        Consumer      15
3     Cheese      30        Consumer      12
4     Cheese      10        Restaurant    18
5     Cheese      20        Restaurant    13
6     Cheese      30        Restaurant    10

我在SQL中使用WHERE子句时遇到问题,根据订购的数量选择客户获得最佳价格的行。规则是他们必须至少满足数量才能获得该定价等级的价格。如果他们的订单低于最低数量,那么他们得到第一个数量的价格(在这种情况下为10),如果他们订购的数量超过最大数量(本例中为30),他们就会得到该价格。

例如......如果餐厅订购了26单位的奶酪,则应选择ID = 5的行。如果消费者订购了9单位的奶酪,那么返回的行应该是ID = 1.如果消费者订购50单位的奶酪,那么他们应该得到ID = 3.

declare @SelectedQuantity INT;

SELECT * 
FROM PriceGuide
WHERE Name = 'Cheese'
  AND ClientType = 'Consumer'
  AND Quantity <= @SelectedQuantity

WHERE子句中缺少什么?

4 个答案:

答案 0 :(得分:1)

修改

第一个解决方案没有正确处理特殊情况,如评论中所述。

接下来尝试:

SELECT TOP 1 ID, Name, Quantity, ClientType, [Price/Unit]
FROM PriceGuide
WHERE Name = 'Cheese'
  AND ClientType = 'Consumer'
ORDER BY CASE WHEN Quantity <= @SelectedQuantity THEN Quantity ELSE -Quantity END DESC

假设Quantity为正数,ORDER BY将首先按降序返回符合Quantity <= @SelectedQuantity条件的行。

对于与此条件不匹配的行,它使用-Quantity进行排序。因此,如果没有符合条件的行,将返回数量最小的行。

答案 1 :(得分:1)

这有点棘手,因为您需要处理小于10的数量。

我认为最好的方法是:

SELECT TOP 1 *
FROM PriceGuide
WHERE Name = 'Cheese' AND ClientType = 'Consumer'
ORDER BY (CASE WHEN @SelectedQuantity >= Quantity THEN 1 ELSE 0 END) DESC, 
         (CASE WHEN @SelectedQuantity >= Quantity THEN PriceUnit END) ASC,
         Quantity ASC;

此版本通过保留给定Name / ClientType的所有行来处理最小数量,使用ORDER BY进行优先排序。

答案 2 :(得分:0)

您的查询将返回小于@SelectedQuantity的所有匹配行。您只想返回数量小于所选数量的行,因此需要子查询来获得此结果:

SELECT * 
FROM PriceGuide a
WHERE a.Name = 'Cheese'
  AND a.ClientType = 'Consumer'
  AND a.Quantity = (SELECT MAX(Quantity) FROM PriceGuide
  WHERE ClientType = a.ClientType
  AND Name = a.Name
  AND Quantity <= @SelectedQuantity)

答案 3 :(得分:0)

在26单元的示例中,您的查询将返回第4行和第5行,而您只需要返回第5行。

display: inline-block