2011-12-23 1 views
2

Я часто, когда я вытягивать данные для анализа, что я группа количество заказов клиент поместил в диапазоны, такие как:Произвольный запрос Вывод заказа с помощью функции CASE-

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

Я делаю это с CASE функции. Тем не менее, когда вы получите результаты запроса, диапазоны заказа будут перечислены как:

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

Этом легко исправить в Excel, когда у вас есть 1 запрос и несколько групп диапазонов заказов. Однако, когда вы тянете много запросов, это боль, чтобы исправлять это снова и снова.

Каков наилучший способ получить диапазон и заказать его правильно?

вот пример запроса, я хотел бы написать:

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... ? 
+0

Вы не можете 'GROUP BY ... COUNT'. Должна ли «GROUP BY» быть чем-то еще? Также не будет '' ORDER BY COUNT (OrderID) 'работать для вас? –

ответ

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 

, как вы обычно ожидали бы, но обернуть его в superquery присоединения к столу 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, который вы хотите применить, возможно, при создании нового.

Отказ от ответственности: Это спектакль-убийца

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+ 

 Смежные вопросы

  • Нет связанных вопросов^_^