对于我的源表,我以正确的顺序保存了所有“客户的联系历史记录”(从顶部最早的日期开始升序)。我需要做的是将联系人与同一问题相关的行分组。判断一个问题是否相关的方法是根据时间。如果时差<2 weeks then the two cases are related.
“通过或失败”列中的 1 突出显示案例是否已完全解决。 0 表示来自下一行的调用与同一问题相关。
我需要生成此表的摘要,以显示客户针对同一查询多次联系的位置
我正在使用 SQL Server 2012
这是我的源数据的示例。在我的完整表中,我将有多个客户。您可以看到我用颜色编码来显示总共 9 个联系人,但只有 4 个不同的问题。每个客户的联系次数或问题没有固定数量
客户_ID | 开始日期 | 下一个_日期 | 时差_(分钟) | 联系人总数 | 通过或失败 | NEXT_Contact_same_day |
---|---|---|---|---|---|---|
12345 | 2022年3月3日 | 2022年5月5日 | 90794 | 1 | 1 | 0 |
12345 | 2022年5月5日 | 2022年5月5日 | 3 | 1 | 0 | 1 |
12345 | 2022年5月5日 | 2022年6月5日 | 1409 | 1 | 0 | 0 |
12345 | 2022年6月5日 | 2022年6月5日 | 2 | 1 | 0 | 1 |
12345 | 2022年6月5日 | 2022年6月5日 | 11 | 1 | 0 | 1 |
12345 | 2022年6月5日 | 20/11/2022 | 284973 | 1 | 1 | 0 |
12345 | 20/11/2022 | 2023年5月1日 | 66242 | 1 | 1 | 0 |
12345 | 2023年5月1日 | 2023年5月1日 | 178 | 1 | 0 | 1 |
12345 | 2023年5月1日 | 空 | 空 | 1 | 1 | 0 |
我尝试在“通过”或“失败”列上使用 DENSE_RANK、ROW_NUMBER、LAG&LEAD,以及开始日期和下一个日期的最大和最小日期,但没有任何运气。
例如
select Customer ID, sum(total_contacts), min(Start date), max(Next Date)
from (select *,
sum(case when Pass or fail = 0 then 1 else 0 end) over (order by Customer ID) as grp
from #Mastery
) #Mastery
where total_contacts = '1'
group by Customer ID, grp;
-- 这将返回所有联系人
select Customer ID, sum(total_contacts) AS total_Contacts, SUM (Pass or fail) AS Pass#, min(Start date) AS Mindate, max(Next Date) AS Maxdate,
ROW_NUMBER () over(partition by Customer ID order by Pass or fail) as Contactranking
from #Mastery2
group by Customer ID, Pass or fail
-- 这仅返回通过和失败的总和
这是我正在寻找的输出。您可以看到,针对相同的客户 ID,我有 4 行,一行代表每个问题。对于每一行,它应该显示针对该问题的调用数量。要量化与同一问题相关的呼叫数量,您必须使用“通过或失败”列
这是一个间隙和岛式问题,您对分组有正确的想法,但有一些细节使这有点棘手。这是一个潜在的解决方案:
SELECT CustomerID, MIN(startDate) startDate, NULLIF(MAX(nextDate), '99991231') nextDate, COUNT(*) cnt
FROM (
select *
, SUM(passprev) OVER(partition by customerid order by startDate, nextdate) AS grp
from (
select LAG(passorfail, 1, 0) over(partition by customerid order by d.startDate, d.nextDate) AS passprev
, d.*
, customerID
from (
VALUES (12345, N'03/03/2022', N'05/05/2022', N'90794', 1, 1, 0)
, (12345, N'05/05/2022', N'05/05/2022', N'3', 1, 0, 1)
, (12345, N'05/05/2022', N'06/05/2022', N'1409', 1, 0, 0)
, (12345, N'06/05/2022', N'06/05/2022', N'2', 1, 0, 1)
, (12345, N'06/05/2022', N'06/05/2022', N'11', 1, 0, 1)
, (12345, N'06/05/2022', N'20/11/2022', N'284973', 1, 1, 0)
, (12345, N'20/11/2022', N'05/01/2023', N'66242', 1, 1, 0)
, (12345, N'05/01/2023', N'05/01/2023', N'178', 1, 0, 1)
, (12345, N'05/01/2023', NULL, NULL, 1, 1, 0)
) t (CustomerID,Startdate,NextDate,[TimeDifference(Mins)],total_contacts,Passorfail,[NEXT_Contact_same_day])
CROSS APPLY (
SELECT CONVERT(DATETIME, startdate, 103) AS startDate
, ISNULL(CONVERT(DATETIME, NextDate, 103), '99991231') AS nextDate
) d
) x
) x
GROUP BY customerID, grp
首先也是最重要的,问题是你必须获取之前的
passorfail
列,因为通常当你创建间隙和岛屿总和时,你希望将值保持为 0,直到新的组到达,而这里为 1创建一个新组。因此我使用LAG(passorfail, 1, 0)
。
这里的排序也有点棘手,因为你有多个重复的日期。为此,我通过
ISNULL(CONVERT(DATETIME, NextDate, 103), '99991231')
创建了决胜局,以便开放日期结束。它还简化了以后的 MAX 处理。
其余的没什么特别的,除了我们用
NULLIF(MAX(nextDate), '99991231')
将日期翻转回空
几点注意:您应该以表格格式提供测试数据。另外,DD/MM/YYYY 是一种非常不方便的日期样式,YYYYMMDD 更好。