我正在尝试计算过去3个月和6个月内活跃的客户数量。
SELECT COUNT (DISTINCT CustomerNo)
FROM SalesDetail
WHERE InvoiceDate > (GETDATE() - 180) AND InvoiceDate < (GETDATE() - 90)
SELECT COUNT (DISTINCT CustomerNo)
FROM SalesDetail
WHERE InvoiceDate > (GETDATE() - 90)
但是,基于上述查询,我将获得过去3个月和最近6个月都处于活动状态的客户数量,即使有重复的客户也是如此。
我如何过滤客户,以便如果客户A在过去3个月和6个月内都处于活动状态,则只会在“过去3个月内处于活动状态”查询中,而不是在“活动中”也是在过去六个月内。
答案 0 :(得分:1)
我这样解决这个问题 让我们考虑一下您有下表。您可能会有更多的列,但是对于想要的结果,我们只需要他们购买商品的 customer_id 和 date 。
CREATE TABLE [dbo].[customer_invoice](
[id] [int] IDENTITY(1,1) NOT NULL,
[customer_id] [int] NULL,
[date] [date] NULL,
CONSTRAINT [PK_customer_invoice] PRIMARY KEY([id]);
我在此表上创建了此示例数据
INSERT INTO [dbo].[customer_invoice]
([customer_id]
,[date])
VALUES
(1,convert(date,'2019-12-01')),
(2,convert(date,'2019-11-05')),
(2,convert(date,'2019-8-01')),
(3,convert(date,'2019-7-01')),
(4,convert(date,'2019-4-01'));
我们不要试图直接跳到最终解决方案上,而是每次都要跳一次。
SELECT customer_id, MIN(DATEDIFF(DAY,date,GETDATE())) AS lastActiveDays
FROM customer_invoice GROUP BY customer_id;
上面的查询为您提供了每个客户活跃之前的天数
customer_id lastActiveDays
1 15
2 41
3 168
4 259
现在,我们将把此查询用作子查询,并添加一个新列 ActiveWithinCategory ,以便在以后的步骤中可以按列对数据进行分组。
SELECT customer_id, lastActiveDays,
CASE WHEN lastActiveDays<90 THEN 'active within 3 months'
WHEN lastActiveDays<180 THEN 'active within 6 months'
ELSE 'not active' END AS ActiveWithinCategory
FROM(
SELECT customer_id, MIN(DATEDIFF(DAY,date,GETDATE())) AS lastActiveDays
FROM customer_invoice GROUP BY customer_id
)AS temptable;
此查询为您提供以下结果
customer_id lastActiveDays ActiveWithinCategory
1 15 active within 3 months
2 41 active within 3 months
3 168 active within 6 months
4 259 not active
现在将上述全部内容用作子查询,并使用 ActiveWithinCategory
对数据进行分组SELECT ActiveWithinCategory, COUNT(*) AS NumberofCustomers FROM (
SELECT customer_id, lastActiveDays,
CASE WHEN lastActiveDays<90 THEN 'active within 3 months'
WHEN lastActiveDays<180 THEN 'active within 6 months'
ELSE 'not active' END AS ActiveWithinCategory
FROM(
SELECT customer_id, MIN(DATEDIFF(DAY,date,GETDATE())) AS lastActiveDays
FROM customer_invoice GROUP BY customer_id
)AS temptable
) AS FinalResult GROUP BY ActiveWithinCategory;
这是您的最终结果
ActiveWithinCategory NumberofEmployee
active within 3 months 2
active within 6 months 1
not active 1
如果要实现相同的目的是MySQL数据库 这是最终的查询
SELECT ActiveWithinCategory, count(*) NumberofCustomers FROM(
SELECT MIN(DATEDIFF(curdate(),date)) AS lastActiveBefore,
IF(MIN(DATEDIFF(curdate(),date))<90,
'active within 3 months',
IF(MIN(DATEDIFF(curdate(),date))<180,'active within 6 months','not active')
) ActiveWithinCategory
FROM customer_invoice GROUP BY customer_id
) AS FinalResult GROUP BY ActiveWithinCategory;
答案 1 :(得分:0)
我怀疑您要在此处进行条件聚合:
SELECT
CustomerNo,
COUNT(CASE WHEN InvoiceDate > GETDATE() - 90 THEN 1 END) AS cnt_last_3,
COUNT(CASE WHEN InvoiceDate > GETDATE() - 180 AND InvoiceDate < GETDATE() - 90
THEN 1 END) AS cnt_first_3
FROM yourTable
GROUP BY
CustomerNo;
这里cnt_last_3
是最近3个月的计数,cnt_first_3
是从6个月前到3个月前的3个月内的计数。
答案 2 :(得分:0)
如果您想要不重复计数,可以像这样添加不重复
Select
count( Case when dt between getdate()- 90 and getdate() then id else null end) cnt_3_months
,count(distinct Case when dt between getdate() - 180 and getdate() - 90 then id else null end) cnt_6_months
from a