从特定客户群体中购买一定比例的产品

时间:2019-02-10 07:06:50

标签: sql postgresql

问题很简单,例如我们有一张包含客户,购买和产品的表格。客户(cust_id,名称,状态)包含所有用户数据,购买包含购买数据(数量,价格,prod_id,cust_id),产品包含产品信息(prod_id,描述)。

比方说,我有10位顾客,其中十分之六购买了鞋子,其中六分之二购买了鞋带。

我的目标是吸引这6个买鞋的顾客,然后得到这6个买鞋带的顾客的百分比。所以我的百分比应该在33.33%左右。

我尝试使用INNER JOINS多次执行此操作,但似乎没有 我做对了。我对这个简单问题的查询确实很杂乱,并且在过去的几天里我一直试图解决此问题。 PS我是SQL查询的新手。我从来没有做过这些复杂的查询。

WITH state_product(customers_id, products_id) AS (
    SELECT DISTINCT customers.id, products.id 
    FROM customers 
    INNER JOIN purchases ON purchases.customer_id = customers.id 
    INNER JOIN products ON purchases.product_id = products.id 
    WHERE products.id = 7
), WITH specific_product(customers_id, products_id) AS (
    SELECT DISTINCT customers.id, products.id from customers 
    INNER JOIN purchases ON purchases.customer_id = customers.id 
    INNER JOIN products ON purchases.product_id = products.id 
    INNER JOIN state_product ON customers.id = 
    state_product.customers_id WHERE products.id = 8),
SELECT SUM(*)/COUNT(state_product.customer_id)*100 
AS Percentage 
FROM specific_product;

编写此代码时,我的逻辑是得到所有唯一的customers.id并以products.id的鞋子PK购买表的鞋子,并7并调用该表{{1 }}。

然后从该state_product中获得与客户的另一张桌子,并仅获得将鞋带state_product购买为products.id = 8的客户。该给我两个specific_product

现在得到的百分比是,我只得到customers.id记录的总和,该总和为2,然后将其除以specific_product的总和,然后乘以100,然后将其放入称为{{ 1}}。那应该是(2/6)* 100 = 33.33%

我愿意采用一种更简单的方法来解决此问题,我的问题是我需要更多的时间来学习SQL查询,而在使用哪些步骤来解决查询问题时,我的逻辑并不像我想的那样清晰。使用Ruby或JS来解决这个问题。鼓励建设性批评。

4 个答案:

答案 0 :(得分:2)

问题

  • 假设我有10位顾客,其中十分之六购买了鞋子,其中六分之二购买了鞋带。

  • 我的目标是吸引这6个买鞋的顾客,然后得到这6个买鞋带的顾客的百分比。所以我的百分比应该在33.33%左右。

用户输入

  • -3张桌子

  • -客户(cust_id,名称,州)

  • -购买(数量,价格,prod_id,cust_id)
  • -产品信息(prod_id,说明)

他们购买的物品清单。

  select 
    b.cust_id,c.description as product
    into #temp
    from purchase a join customers b on a.cust_id = b.cust_id
    join product_info c on a.prod_id = c.prod_id
    where c.description in ('shoes','laces')

现在查询逻辑

select 
    t1.cust_id,
    sum(case 
       when t2.cust_id is null then 0
       else 1
    end) totalCustomersWithLaces
into #t2
    from      
         (
            --List of customers who bought shoes
            select distinct cust_id from #temp
            where product = "shoes"
         )t1 left join 
         (
        --List of customers who bought laces
            select distinct cust_id from #temp
            where product = "laces"
         )t2 on t1.cust_id = t2.cust_id

最后得到结果

select sum(totalCustomersWithLaces)/cast(count(1) as float) from #t2

答案 1 :(得分:0)

使用条件聚合。

select 100 * count(*) /
       count(
         case when prod_id = 2 -- lace prod_id
              then 1
         end
       ) percent
from purchases
where prod_id = 1 -- shoe prod_id

答案 2 :(得分:0)

下面是查询

数据-

Customers
c1      cust1   KA
c2      cust3   KA
c3      cust3   KA
c4      cust4   KA
c5      cust5   KA
c6      cust6   KA

购买

cust_id prod_id quantity price
c1      P1      1       10
c1      P2      1       2
c2      P1      1       10
c2      P2      1       2
c3      P1      1       10
c3      P2      2       2
c4      P1      1       10
c4      P2      1       2
c5      P1      2       10

产品详细信息

prod_id prod_desc
P1      shoes
P2      laces

您的查询将是-

select
 --c.cust_id, p.prod_id, pd.prod_desc
 (sum(case when pd.prod_desc='laces' then 1 else 0 end)/
 sum(case when pd.prod_desc='shoes' then 1 else 0 end)) * 100
from customers c
inner join purchases p on c.cust_id=p.cust_id
inner join product pd on p.prod_id=pd.prod_id
where pd.prod_desc in ('shoes', 'laces');

如果要基于数量进行计算,如果客户带来2鞋和1鞋带怎么办

select
 --c.cust_id, p.prod_id, pd.prod_desc
 (sum(case when pd.prod_desc='laces' then quantity else 0 end)/
 sum(case when pd.prod_desc='shoes' then quantity else 0 end)) * 100
from customers c
inner join purchases p on c.cust_id=p.cust_id
inner join product pd on p.prod_id=pd.prod_id
where pd.prod_desc in ('shoes', 'laces');

答案 3 :(得分:0)

一种方法是:

select avg( (cnt_8 > 0)::int ) as ratio_8_to_7
from (select pc.customer_id,
             count(*) filter (where p.product_id = 7) as cnt_7,
             count(*) filter (where p.product_id = 8) as cnt_8
      from purchases p
      where p.product_id in (7, 8)
      group by p.customer_id
     ) pc
where cnt_7 > 0;

这是做什么的?内部子查询为每个客户总结该客户对每种产品的购买数量。因为您只关心这两种产品,所以where子句将其他所有内容过滤掉了。

外部查询然后计算购买“ 7”的客户中产品“ 8”与产品“ 7”的比率。

非常非常重要:这是客户,而不是购买。因此,多次购买鞋带或鞋子的客户只计算一次。那是我对你问题的解释。