自定义查询输出使用CASE函数进行排序

时间:2011-12-23 22:25:02

标签: sql-server group-by sql-order-by case

我经常发现,当我提取数据进行分析时,我会将客户的订单数量分组到范围内,例如:

1-2
3-5
6-9
10-12
13-15

我使用CASE函数执行此操作。但是,当您获得查询结果时,订单范围将列为:

1-2
10-12
13-15
3-5
6-9

当您有1个查询和几个订单范围组时,这在Excel中很容易纠正。但是,当你提出很多疑问时,一遍又一遍地纠正这个问题是很痛苦的。

拉出范围并正确订购的最佳方法是什么?

这是我要写的查询示例:

SELECT 
    OrderRange = CASE
        WHEN COUNT(OrderID) BETWEEN 1 AND 5 THEN '1-5'
        WHEN COUNT(OrderID) BETWEEN 6 AND 10 THEN '6-10'
        WHEN COUNT(OrderID) > 10 THEN '10+'
        ELSE 'Error'
    END
FROM Orders
GROUP BY CASE
    WHEN COUNT(OrderID) BETWEEN 1 AND 5 THEN '1-5'
    WHEN COUNT(OrderID) BETWEEN 6 AND 10 THEN '6-10'
    WHEN COUNT(OrderID) > 10 THEN '10+'
    ELSE 'Error'
    END
ORDER BY...  ?

2 个答案:

答案 0 :(得分:3)

我会保留一个范围表,例如(指数未写)

CREATE TABLE Ranges (RangeSet int, MinVal int, MaxVal int, Name varchar(50));

然后例如

INSERT INTO ranges VALUES
  (1,1,5,'1-5'),(1,6,10,'6-10'),(1,11,-1,'11+'),
  (2,1,10,'1-10'),(2,11,20,'11-20'),(2,21,30,'21-30'),(2,31,-1,'31+');

你明白了。现在你做一些事情(表和字段名称免费小说)

SELECT
  CustomerID,
  count(OrderID) AS OrderCount
FROM Orders
WHERE <whatever, e.g order_date BETWEEN ... AND ...>
GROUP BY CustomerID
HAVING OrderCount>0
正如您通常所期望的那样

,但将其包装在加入Ranges表的超级查询中

SELECT
  BaseView.CustomerID as CustomerID,
  Ranges.Name as OrderRange
FROM (
  SELECT
    CustomerID,
    count(OrderID) AS OrderCount
  FROM Orders
  WHERE <whatever, e.g order_date BETWEEN ... AND ...>
  GROUP BY CustomerID
  HAVING OrderCount>0
) AS BaseView
INNER JOIN Ranges ON
  Ranges.RangeSet=<id-of-required-rangeset>
  AND BaseView.OrderCount>=Ranges.MinVal
  AND (BaseView.OrderCount<=Ranges.MaxVal OR Ranges.MaxVal=-1)
ORDER BY RangeSet.MinVal DESC
;

现在您只需要提供要应用的RangeSet,有时可能会创建一个新的。

免责声明:这是一个性能杀手

答案 1 :(得分:2)

如果我正确理解您,您希望客户列表和订单范围从最低到最高排序。你应该能够通过计数(orderID)

来排序
SELECT CustomerID,
    OrderRange = CASE
    WHEN COUNT(OrderID) BETWEEN 1 AND 5 THEN '1-5'
    WHEN COUNT(OrderID) BETWEEN 6 AND 10 THEN '6-10'
    WHEN COUNT(OrderID) > 10 THEN '10+'
    ELSE 'Error'
END ,
FROM Orders
GROUP BY CustomerID
order by count(orderid)

结果:

CustomerId  OrderRange
CENTC   1-5
GROSR   1-5
LAZYK   1-5
...
ROMEY   1-5
VINET   1-5
ALFKI   6-10
CACTU   6-10
...
VICTE   6-10

WANDK   6-10
BLONP   10+
GREAL   10+
RICAR   10+
...
QUICK   10+
ERNSH   10+
SAVEA   10+