Sql server 如何从count distinct查询中筛选出

Sql server 如何从count distinct查询中筛选出,sql-server,tsql,Sql Server,Tsql,我试图计算过去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个月活跃的客户数量

SELECT COUNT (DISTINCT CustomerNo)
FROM SalesDetail
WHERE InvoiceDate > (GETDATE() - 180) AND InvoiceDate < (GETDATE() - 90)

SELECT COUNT (DISTINCT CustomerNo)
FROM SalesDetail
WHERE InvoiceDate > (GETDATE() - 90)

选择计数(不同的客户号)
来自SalesDetail
其中InvoiceDate>(GETDATE()-180)和InvoiceDate<(GETDATE()-90)
选择计数(不同的客户编号)
来自SalesDetail
其中InvoiceDate>(GETDATE()-90)
然而,根据上面的查询,我将获得在过去3个月和过去6个月内一直处于活动状态的count Customers,即使存在类似的重复项

  • 客户A在过去3个月内购买了一次
  • 客户A在过去6个月内也购买了一次

如何筛选出客户,以便如果客户A在过去3个月和6个月内都处于活动状态,则他/她将只计入“过去3个月内处于活动状态”查询中,而不计入“过去6个月内处于活动状态”查询中。

我怀疑您想在此处进行条件聚合:

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;
选择
客户号,
将(InvoiceDate>GETDATE()-90然后1结束时的情况)计数为cnt_last_3,
计数(当InvoiceDate>GETDATE()-180和InvoiceDate

这里的
cnt\u last\u 3
是最近3个月内的计数,
cnt\u first\u 3
是从6个月前开始到3个月前结束的3个月期间的计数。

如果您想要不同的计数,可以这样添加不同的计数

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

我用这种方法解决这个问题 让我们考虑一下下表。您可能会有更多列,但为了得到您想要的结果,我们只需要客户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;
现在,将上述全部内容用作子查询,并使用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;
如果想实现同样的东西就是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;
选择ActiveWithinCategory,从中计算(*)客户数(
选择MIN(DATEDIFF(curdate(),date))作为lastActiveBefore,

如果(MIN(DATEDIFF(curdate(),date))您能分享一些输出数据以便更好地理解吗?是的,这正是我试图解决的问题。非常感谢您的帮助,先生。
ActiveWithinCategory    NumberofEmployee
active within 3 months      2
active within 6 months      1
not active                  1
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;