同一天多次购买的重复顾客算1

问题描述 投票:0回答:4

我正在努力解决这个问题。 我被要求创建一份报告,显示我们数据库中的回头客。

其中一个要求是,如果客户在特定日期有超过 1 个订单,则仅算作 1 个。 然后,如果他们有超过 1 个购买日期,他们将被视为回头客。

在这里搜索,我发现这适用于查找在特定购买日期购买超过 1 次的客户。

SELECT DISTINCT s.[CustomerName], s.PurchaseDate

FROM Reports.vw_Repeat s WHERE s.PurchaseDate <> ''    

GROUP BY s.[CustomerName] , cast(s.PurchaseDate as date)

HAVING COUNT(*) > 1;

此 MSSQL 代码按其应有的方式工作,显示在同一日期进行了 1 次以上购买的客户。 我的问题是,最好的方法是将其加入到另一个查询中(这是我需要帮助的地方),然后显示完整的重复客户列表,其中购买次数超过 1 次的客户将被返回。

我正在使用 MSSQL。 任何帮助将不胜感激。

sql-server repeat
4个回答
0
投票

您已经很接近了,您需要将

distinct
移至您的
having
子句中,因为您只想包含具有超过 1 个不同购买日期的客户。

此外,仅按客户 ID 进行分组,因为不同的日期必须属于同一组才能使

count distinct
正常工作。

SELECT s.[CustomerName], COUNT(distinct cast(s.PurchaseDate as date))
FROM Reports.vw_Repeat s WHERE s.PurchaseDate <> ''    
GROUP BY s.[CustomerName] 
HAVING COUNT(distinct cast(s.PurchaseDate as date)) > 1;

0
投票

如果您想将参数传递给查询并连接结果,这就是表值函数的用途。当您加入它时,您使用 CROSS APPLY 或 OUTER APPLY 而不是 INNER JOIN 或 LEFT JOIN。

另外,我认为这是不言而喻的,但是当你检查PurchaseDate是否为空时:

WHERE s.PurchaseDate <> '' 

可能存在问题...这意味着它是一个 varchar 字段而不是日期时间(是吗?)并且不处理空值。您可能至少希望将其替换为 ISNULL(s.PurchaseDate, '') <> ''。如果它实际上是日期时间,请使用 IS NOT NULL 而不是 <> ''。

(编辑以添加示例数据和 DDL 语句。我建议将这些添加到 SQL 帖子中以帮助回答者。此外,由于查询中的字符串比较,我购买了 varchar 而不是日期时间。)

https://technet.microsoft.com/en-us/library/ms191165(v=sql.105).aspx

CREATE TABLE company (company_name VARCHAR(25))
INSERT INTO company VALUES ('Company1'), ('Company2')

CREATE TABLE vw_repeat (customername VARCHAR(25), purchasedate VARCHAR(25), company VARCHAR(25))
INSERT INTO vw_repeat VALUES ('Cust1', '11/16/2017', 'Company1')
INSERT INTO vw_repeat VALUES ('Cust1', '11/16/2017', 'Company1')
INSERT INTO vw_repeat VALUES ('Cust2', '11/16/2017', 'Company2')

CREATE FUNCTION [dbo].tf_customers
(
    @company varchar(25)    
)
RETURNS TABLE AS RETURN
(
    SELECT s.[CustomerName], cast(s.PurchaseDate as date) PurchaseDate
    FROM vw_Repeat s 
    WHERE s.PurchaseDate <> '' AND s.Company = @company 
    GROUP BY s.[CustomerName] , cast(s.PurchaseDate as date)
    HAVING COUNT(*) > 1
)
GO

SELECT * 
FROM company c
CROSS APPLY tf_customers(c.company_name)

0
投票

首先感谢大家的帮助。 @MaxSzczurek 建议我使用表值函数。经过更多研究后,我最终仅使用临时表来获取每个客户的不同购买日期。 然后我将其加载到与主表右连接的另一个临时表中。 这给了我我正在寻找的结果。 它有点(很多)丑陋,但它有效。


0
投票

我用过:

dense_rank() over(按客户名称顺序按日期升序分区)

为了获得每个客户的购买顺序,但将同一客户同一天的多次购买计算为相同的购买数量(按顺序)。

© www.soinside.com 2019 - 2024. All rights reserved.