【问题标题】:SQL. Find the customers who bought same brands and at-least 2 products in each brandSQL。找到购买相同品牌且每个品牌至少有 2 件产品的客户
【发布时间】:2020-10-21 06:30:09
【问题描述】:

我有两张桌子:

Sales
columns:  (Sales_id, Date, Customer_id, Product_id, Purchase_amount):
Product 
columns:  (Product_id, Product_Name, Brand_id,Brand_name)

我必须编写一个查询来查找购买了品牌“X”和“Y”(两者)以及每个品牌至少 2 件产品的客户。以下查询是否正确?有什么建议的更改吗?

SELECT S.Customer_id "Customer ID"
FROM Sales S LEFT JOIN Product P
ON S.Product_id = P.Product_id
AND P.Brand_Name IN ('X','Y')
GROUP BY S.Customer_id
HAVING COUNT(DISTINCT S.Product_id)>=2 -----at least 2 products in each brand
 AND COUNT(S.Customer_id) =2 ---------------customers who bought both brands

任何帮助将不胜感激。提前致谢

【问题讨论】:

    标签: sql oracle select count db2


    【解决方案1】:

    使用COUNT()窗口函数统计每个客户购买的不同品牌的数量和每个品牌的不同产品的数量。
    然后使用HAVING 子句过滤掉没有购买这两个品牌的客户和GROUP BY 客户,该子句过滤掉没有购买至少两个品牌的产品的客户。
    此外,您的加入应该是 INNER 加入,而不是 LEFT 加入。

    select t.customer_id "Customer ID" 
    from (
      select s.customer_id,
        count(distinct p.brand_id) over (partition by s.customer_id) brands_counter,
        count(distinct p.product_id) over (partition by s.customer_id, p.brand_id) products_counter
      from sales s inner join product p
      on p.product_id = s.product_id
      where p.brand_name in ('X', 'Y')
    ) t
    where t.brands_counter = 2
    group by t.customer_id
    having min(t.products_counter) >= 2
    

    【讨论】:

    • 您的解决方案对我帮助很大。谢谢。另外,感谢您在我的查询中提出 JOIN 错误。
    【解决方案2】:

    从您现有的查询开始,您可以使用以下HAVING 子句:

    HAVING 
        AND COUNT(DISTINCT CASE WHEN p.brand_name = 'X' then S.product_id end) >= 2
        AND COUNT(DISTINCT CASE WHEN p.brand_name = 'Y' then S.product_id end) >= 2
    

    这可确保客户在两个品牌中都购买了至少两种产品。这隐含地保证它在两个品牌中都下订单,因此不需要额外的逻辑。

    你也可以用MIN()MAX()来表达:

    HAVING 
        AND MIN(CASE WHEN p.brand_name = 'X' THEN S.product_id END)
            <> MAX(CASE WHEN p.brand_name = 'X' then S.product_id end)
        AND MIN(CASE WHEN p.brand_name = 'Y' THEN S.product_id END)
            <> MAX(CASE WHEN p.brand_name = 'Y' then S.product_id end)
    

    【讨论】:

      【解决方案3】:

      您可以使用两个级别的聚合:

      SELECT Customer_id
      FROM (SELECT S.Customer_id, S.Brand_Name, COUNT(DISTINCT S.Product_Id) as num_products
            FROM Sales S LEFT JOIN
                 Product P
                 ON S.Product_id = P.Product_id
            WHERE P.Brand_Name IN ('X', 'Y')
            GROUP BY S.Customer_id, S.Product_Id
           ) s
      GROUP BY Customer_Id
      HAVING COUNT(*) = 2 AND MIN(num_products) >= 2;
      

      【讨论】:

      • @Sharon 。 . .这似乎是最简单的解决方案。
      猜你喜欢
      • 1970-01-01
      • 2020-03-06
      • 2020-07-30
      • 2020-03-06
      • 1970-01-01
      • 2013-09-05
      • 2022-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多