在 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_id
与 customer_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
列(具有 DATE
或 TIMESTAMP
数据类型)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
);
我在一个 Oracle 数据库中有两个 table,其中一个是所有客户多年来所做的所有购买 (purchase_logs
)。它有一个唯一的 purchase_id
与 customer_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
列(具有 DATE
或 TIMESTAMP
数据类型)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
);