在 SQL 中显示一个月内购买超过 1 次的所有用户的最佳方法

Best approach to display all the users who have more than 1 purchases in a month in SQL

我在一个 Oracle 数据库中有两个 table,其中一个是所有客户多年来所做的所有购买 (purchase_logs)。它有一个唯一的 purchase_idcustomer_id 配对。另一个 table 包含所有客户的用户信息。两者都有一个公共密钥 customer_id.

我想显示在任何一个月内购买了超过 1 件独特商品(不是商品数量)的客户的用户信息(即,如果客户在 2020 年 2 月购买了 4 件独特商品,它们将有效,并且有人在 6 月购买了 2 件商品)。我想知道我的正确方法应该是什么以及如何正确执行该方法。

我能看到的两种方法是

方法一

统计所有客户完成的购买总数,过滤掉大于 1 的,然后检查他们是否在一个月内完成。 将其用作主查询的 where 子句中的子查询,以检索所有符合此条件的 customer_id 的客户信息。

这是我目前所做的,它检索所有购买次数超过 1 次的客户的客户 ID。但是我不明白如何过滤掉任意一个月内未发生的所有购买。

SELECT * FROM customer_details
WHERE customer_id IN (
SELECT cust_id from purchase_logs
group by  cust_id
having count(*) >= 2);

方法二

创建一个临时的 table 来计算特定 user_id 的每月购买次数,然后找到整个 table 的 MAX() 并检查该 MAX 值是否更大是否大于 1。然后,如果它为 customer_info.

的主查询的 where 子句提供真值

方法 2 感觉更合乎逻辑,但我似乎无法理解如何为其编写正确的子查询,因为命令 MAX(COUNT(customer_id)) from purchase_logs 似乎不是有效查询。

这是 DDL 图。

这是Purchase_logs

的示例数据

Customer_info

Item_info

此示例数据的预期输出为

当然有可能存在一种我现在没有看到的更简单的方法。 对此有任何建议和提示,我们将不胜感激。

I want to display the user info of customers who have more than 1 purchases in a single arbitrary month.

只需将 WHERE 过滤器添加到您的 sub-query。

所以假设您想要 2021 年 7 月,并且您的 purchase_logs 中有一个 purchase_date 列(具有 DATETIMESTAMP 数据类型)table 那么你可以使用:

SELECT *
FROM   customer_details
WHERE  customer_id IN (
         SELECT cust_id
         FROM   purchase_logs
         WHERE  DATE '2021-07-01' <= purchase_date
         AND    purchase_date < DATE '2021-08-01'
         GROUP BY cust_id
         HAVING count(*) >= 2
       );

如果您希望用户在任何一个日历月内购买了 two-or-more 件商品,则:

SELECT *
FROM   customer_details c
WHERE  EXISTS (
         SELECT 1
         FROM   purchase_logs p
         WHERE  c.customer_id = p.cust_id
         GROUP BY cust_id, TRUNC(purchase_date, 'MM')
         HAVING count(*) >= 2
       );

一种方法可能是尝试

with multiplepurchase as (
select customer_id,month(purchasedate),count(*) as order_count
from purchase_logs
group by customer_id,month(purchasedate)
having count(*)>=2)
select customer_id,username,usercategory
from mutiplepurchase a
left join userinfo b
on a.customer_id=b.customer_id

您需要这个查询:

SELECT DISTINCT cust_id 
FROM purchase_logs
GROUP BY cust_id, TO_CHAR(purchase_date, 'YYYY-MON')
HAVING COUNT(DISTINCT item_id) > 1;

获取所有 cust_id 客户 在任何一个月内购买了超过 1 件独特商品的 并且您可以与运算符一起使用 IN:

SELECT * 
FROM customer_details
WHERE customer_id IN (
  SELECT DISTINCT cust_id -- here DISTINCT may be removed as it does not make any difference when the result is used with IN
  FROM purchase_logs
  GROUP BY cust_id, TO_CHAR(purchase_date, 'YYYY-MON')
  HAVING COUNT(DISTINCT item_id) > 1
);

扩展@MT0 回答:

SELECT *
FROM   customer_details CD
WHERE  exists (
         SELECT cust_id
         FROM   purchase_logs PL
         where CD.customer_id = PL.customer_id
         GROUP BY cust_id, item_id, to_char(purchase_date,'YYYYMM')
         HAVING count(*) >= 2
       );