在SQL表中分组

时间:2016-11-08 00:08:57

标签: sql sql-server grouping

假设我有一个表:

|ID  | product |orderid | brand |number of product cust ord| 
|----|---------|--------|-------|--------------------------|   
| 1  |   123   |   111  |   br  |        1                 |
|----|---------|--------|-------|--------------------------| 
| 1  |   234   |   111  |   br  |        1                 |
|----|---------|--------|-------|--------------------------|
| 1  |   345   |   333  |   br  |        1                 |
|----|---------|--------|-------|--------------------------|
| 2  |   123   |   211  |   br  |        1                 |
|----|---------|--------|-------|--------------------------|
| 2  |   456   |   212  |   br  |        2                 |
|----|---------|--------|-------|--------------------------|
| 3  |   567   |   213  |   br  |        1                 |
|----|---------|--------|-------|--------------------------|

我想做的是将它们分组为:

|ID  | brand   |number of product cust ord| 
|----|---------|--------------------------|   
| 1  |   br    |        3                 |
|----|---------|--------------------------| 
| 2  |   br    |        4                 |
|----|---------|--------------------------|

进一步说,我想对他们进行分类并尝试一个案例...但似乎无法做到正确。

如果ID购买超过3种独特产品且订单超过两次 - 我想称他们为常客(在上面的例子中,ID'1'将是'常客'),如果平均数他们购买的产品高于销售产品的平均数量 - 我想称他们为'商家',否则只是购买者。

2 个答案:

答案 0 :(得分:0)

为了简洁起见,我将最后一个字段重命名为qty,并调用了表test1。

要获得常见的传单,请使用以下查询。请注意,我使用的是> =而不是>。我根据你的例子改变了这个,其中ID 1是“常旅客”,即使他只买了3件产品,但不超过3件。

SELECT ID, count(distinct product) as DistinctProducts, count(distinct orderid) DistinctOrders
FROM test1
GROUP BY ID
HAVING count(distinct product)  >= 3 and count(distinct orderid) >= 2

不确定我是否正确理解了商家逻辑。以下是给您的客户平均购买的产品超过任何特定产品的整体平均产品的查询。数据中没有。

SELECT DISTINCT c.ID
FROM 
(select ID, product, avg(qty) as AvgQty
FROM test1
GROUP BY ID, product) as c
FULL OUTER JOIN 
(select product, avg(qty) as AvgQty
FROM test1
GROUP BY product) p ON p.product = c.product
WHERE c.AvgQty > p.AvgQty;

要让所有客户与商家和常客之间的“购买者”之间取得联系:

select distinct ID from test1

EXCEPT 

(SELECT ID FROM (
select ID, count(distinct product) as DistinctProducts, count(distinct orderid) DistinctOrders
FROM test1
GROUP BY ID
HAVING count(distinct product)  >= 3 and count(distinct orderid) >= 2) t

UNION 

SELECT DISTINCT c.ID
FROM 
(select ID, product, avg(qty) as AvgQty
FROM test1
GROUP BY ID, product) as c
FULL OUTER JOIN 
(select product, avg(qty) as AvgQty
FROM test1
GROUP BY product) p ON p.product = c.product
WHERE c.AvgQty > p.AvgQty
);

答案 1 :(得分:-1)

这是你可以做到的一种方式。请注意,根据您提供的说明,买家可能会经常在商家'之间重新分类。和'购买者'随着平均值的上升和下降。那可能不是你想要的。

With cte As (
    Select ID,
        Brand,
        DistinctOrders = Count(Distinct OrderID), -- How many separate orders by this customer for the brand?
        DistinctProducts = Count(Distinct Product), -- How many different products by this customer for the brand?
        [number of product cust ord] = Sum(CountOfProduct), -- Total number of items by this customer for the brand. 
        AverageCountOfProductPerBuyer = 
            Sum(Sum(CountOfProduct)) Over () * 1.0 / (Select Count(*) From (Select Distinct ID, Brand From #table) As tbl) 
            -- Average number of items per customer (for all customers) for this brand
      From #table
      Group By ID, Brand)
Select ID, Brand, DistinctOrders, DistinctProducts, [number of product cust ord],
    IsFrequentBuyer = iif(DistinctOrders > 1 And DistinctProducts > 2, 'Frequent Buyer', NULL),
    IsMerchant = iif(AverageCountOfProductPerBuyer < [number of product cust ord], 'Merchant', 'Purchaser')
  From cte;

这个查询可以在没有common-table表达式的情况下编写,但是这样编写是为了避免多次定义表达式。

请注意,我有第一个ID作为“频繁买家”#39;根据您的描述,我假设当您说“超过3种独特产品”时,我们会根据您的描述进行操作。你的意思是3或更多。同样,有两个或更多不同的订单。