同一天多次购买的回头客计为 1
Repeat Customers with multiple purchases on the same day counts a 1
我正在努力解决这个问题。我被要求创建一个报告来显示我们数据库中的回头客。
其中一个要求是,如果客户在特定日期有超过 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 次的客户将被退回。
我正在使用 MSSQL。任何帮助将不胜感激。
如果您想将参数传递给查询并连接结果,这就是 table 值函数的用途。当你加入它时,你使用 CROSS APPLY 或 OUTER APPLY 而不是 INNER JOIN 或 LEFT JOIN。
此外,我认为这是不言而喻的,但是当您检查 PurchaseDate 是否为空时:
WHERE s.PurchaseDate <> ''
那里可能有问题...这意味着它是一个 varchar 字段而不是日期时间(是吗?)并且不处理空值。至少,您可能希望将其替换为 ISNULL(s.PurchaseDate, '') <> ''。如果它实际上是一个日期时间,请使用 IS NOT NULL 而不是 <> ''。
(已编辑以添加示例数据和 DDL 语句。我建议将这些添加到 SQL 帖子以帮助回答者。此外,由于查询中的字符串比较,我购买了一个 varchar 而不是 datetime。 )
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)
你很接近,你需要将 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;
首先感谢大家的帮助。
@MaxSzczurek 建议我使用 table 值函数。在进一步研究之后,我最终只使用了一个临时的 table 首先来获取每个客户的 DISTINCT 购买日期。然后我将它加载到另一个临时 table 右加入到主 table。这给了我想要的结果。它有点(很多)丑陋,但它有效。
我正在努力解决这个问题。我被要求创建一个报告来显示我们数据库中的回头客。
其中一个要求是,如果客户在特定日期有超过 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 次的客户将被退回。
我正在使用 MSSQL。任何帮助将不胜感激。
如果您想将参数传递给查询并连接结果,这就是 table 值函数的用途。当你加入它时,你使用 CROSS APPLY 或 OUTER APPLY 而不是 INNER JOIN 或 LEFT JOIN。
此外,我认为这是不言而喻的,但是当您检查 PurchaseDate 是否为空时:
WHERE s.PurchaseDate <> ''
那里可能有问题...这意味着它是一个 varchar 字段而不是日期时间(是吗?)并且不处理空值。至少,您可能希望将其替换为 ISNULL(s.PurchaseDate, '') <> ''。如果它实际上是一个日期时间,请使用 IS NOT NULL 而不是 <> ''。
(已编辑以添加示例数据和 DDL 语句。我建议将这些添加到 SQL 帖子以帮助回答者。此外,由于查询中的字符串比较,我购买了一个 varchar 而不是 datetime。 )
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)
你很接近,你需要将 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;
首先感谢大家的帮助。 @MaxSzczurek 建议我使用 table 值函数。在进一步研究之后,我最终只使用了一个临时的 table 首先来获取每个客户的 DISTINCT 购买日期。然后我将它加载到另一个临时 table 右加入到主 table。这给了我想要的结果。它有点(很多)丑陋,但它有效。