我正在尝试计算过去 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 个月内购买了一次
- 客户 A 在过去 6 个月内也购买过一次
我如何过滤掉客户,这样如果客户 A 在过去 3 个月和 6 个月都活跃,他/她将只被计入“过去 3 个月活跃”查询而不是“活跃”过去 6 个月也是如此。
最佳答案
我是这样解决这个问题的 让我们考虑您有下表。您可能有更多列,但对于您想要的结果,我们只需要 customer_id 和他们购买商品的日期。
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;
关于sql-server - 如何从计数不同的查询中过滤掉,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59350691/