sql - 统计过去 12 个月内提交过罚单的所有人数 每月分组
问题描述
我有这些示例表:
CREATE TABLE #tmp_persons (
PersonID int primary key identity
, FirstName varchar(max)
, LastName varchar(max)
)
CREATE TABLE #tmp_tickets (
TicketNum int primary key identity
, Title varchar(max)
, Descr varchar(max)
, DateFiled datetime
, SubmittedBy int FOREIGN KEY REFERENCES #tmp_persons(PersonID)
)
CREATE TABLE #tmp_assigned_lead (
AssignmentID int primary key identity
, PersonID int FOREIGN KEY REFERENCES #tmp_persons(PersonID) -- ID of the Lead
, AssignedPersonID int FOREIGN KEY REFERENCES #tmp_persons(PersonID) -- ID of the person assigned
)
-- DATA DUMP
INSERT INTO #tmp_persons
VALUES
(1, 'John', 'Doe'), (2, 'Jane', 'Doe'),
(3, 'Carl', 'Smith'), (4, 'Jenny', 'Smith'),
(5, 'John', 'Wick'), (6, 'Stephanie', 'Mathews')
INSERT INTO #tmp_assigned_lead (PersonID, AssignedPersonID)
VALUES
(1, 2), (1, 3), (1, 4), (1, 5), (1, 6)
INSERT INTO #tmp_tickets (Title, Descr, DateFiled, SubmittedBy)
VALUES
('Ticket 1', 'blah', '01-01-2019', 2),
('Ticket 2', 'blah', '01-02-2019', 2),
('Ticket 3', 'blah', '05-01-2019', 4),
('Ticket 4', 'blah', '05-01-2019', 2),
('Ticket 5', 'blah', '06-01-2019', 5),
('Ticket 6', 'blah', '07-01-2019', 6),--
('Ticket 7', 'blah', '4-17-2018', 6),
('Ticket 8', 'blah', '12-30-2018', 6),
('Ticket 9', 'blah', '1-28-2019', 3),
('Ticket 10', 'blah', '3-16-2019', 3),
('Ticket 11', 'blah', '3-30-2018', 5),
('Ticket 12', 'blah', '2-4-2018', 4),
('Ticket 13', 'blah', '1-11-2019', 6),
('Ticket 14', 'blah', '9-5-2018', 6)
所以这里有几点:
- 每个人都
#tmp_persons
可以有一个“潜在客户”,这存储在一个关系表中#tmp_assigned_lead
。 - 一个人可以提交存储在
#tmp_tickets
- 一个人在提交罚单时被称为“a”
Contributor
,但如果他在 12 个月内未提交另一张罚单,则作为普通会员返回。
Contributor
现在我的要求是,我想统计每个月过渡到领导下的所有人。这将是每月的记录。
示例场景:
Person1
已注册Jan 01, 2018
并且从那以后就再也没有提交过罚单,直到Jan 01, 2019
他提交了他的第一张罚单。这将仅适用Person1
于Contributor
2019 年 1 月,但他Jan 2018
是Dec 2018
.Person1
提交了另一张罚单Feb 2019
。虽然他提交了新的票,但他仍然没有被计入Feb 2019
成为成员的记录,Contributor
因为他已经Contributor
是Jan 2019
Person2
已注册Feb 23, 2019
并立即提交了罚单。这使他/她成为 1Contributor
月份“成为贡献者的成员”的计数Feb 2019
。
到目前为止,我提出的这个查询将每人和每月的票分组:
SELECT
SubmittedBy
, MaxDate = MAX(DateFiled)
, PeriodMonth = MONTH(DateFiled)
, PeriodYear = YEAR(DateFiled)
FROM #tmp_tickets
GROUP BY
SubmittedBy
, MONTH(DateFiled)
, YEAR(DateFiled)
这就是我遇到的障碍。我想不出一个查询将返回一个潜在客户下的成员数,谁成为Contributors
.
这就是我到目前为止所拥有的。我将上述查询用作CTE
:
;with cte as (
SELECT
SubmittedBy
, MaxDate = MAX(DateFiled)
, PeriodMonth = MONTH(DateFiled)
, PeriodYear = YEAR(DateFiled)
FROM #tmp_tickets
GROUP BY
SubmittedBy
, MONTH(DateFiled)
, YEAR(DateFiled)
)
SELECT
lead.PersonID
, ContributorsCnt = COUNT(1)
, PeriodMonth
, PeriodYear
FROM #tmp_assigned_lead lead
INNER JOIN cte
ON lead.AssignedPersonID = cte.SubmittedBy
-- WHERE??
-- check if member has no tickets in the past 12 months
GROUP BY
lead.PersonID
, PeriodMonth
, PeriodYear
编辑:
添加了数据转储和分析点。
要点:
2018 年 2 月,PersonID 4 成为贡献者。除了他,没有人提出过罚单。这会给我们一行:
LeadID: 1, PeriodYear: 2018, PeriodMonth: 2, Contributor: 1
在 2018 年 3 月,PersonID 5 成为了贡献者。同样,这将为我们提供另一行:
LeadID: 1, PeriodYear: 2018, PeriodMonth: 3, Contributor: 1
2018 年 4 月,PersonID 6 成为贡献者:
LeadID: 1, PeriodYear: 2018, PeriodMonth: 4, Contributor: 1
从 2018-05 到 2019-01,没有其他人成为贡献者。此处的 PersonID 6 不计算在内,因为他仍然是贡献者。
在 2019-01,PersonID 2 和 3 成为贡献者。这是他们第一次提交罚单。同样,PersonID 6 仍然是贡献者。这会给我们一行:
LeadID: 1, PeriodYear: 2019, PeriodMonth: 1, Contributor: 2
2019 年 2 月,PersonID 4 重新成为普通会员,而不是贡献者,因为已经 12 个月了,从那以后他没有提交任何票。为此不需要行。
在 2019 年 3 月,PersonID 5 成为普通成员(与第 6 点相同的逻辑)。第 3 个人提交了一张票,但他仍然是贡献者。总的来说,不需要行。
在 2019 年 5 月,第 2 个人提交了一张票,但他仍然是贡献者。第 4 个人提交了工单,他已经是普通会员,所以他现在是贡献者:
LeadID: 1, PeriodYear: 2019, PeriodMonth: 5, Contributor: 1
在 2019-06,Person 5 成为贡献者:
LeadID: 1, PeriodYear: 2018, PeriodMonth: 5 Contributor: 1
在 2019 年 7 月,第 6 个人提交了一张票,但自从他的最后一张票于 2019 年 1 月提交后,他仍然是贡献者。(真是个大忙人!)
预期数据集:
LeadID: 1, PeriodYear: 2018, PeriodMonth: 2, Contributor: 1
LeadID: 1, PeriodYear: 2018, PeriodMonth: 3, Contributor: 1
LeadID: 1, PeriodYear: 2018, PeriodMonth: 4, Contributor: 1
LeadID: 1, PeriodYear: 2019, PeriodMonth: 1, Contributor: 2
LeadID: 1, PeriodYear: 2019, PeriodMonth: 5, Contributor: 1
LeadID: 1, PeriodYear: 2018, PeriodMonth: 5 Contributor: 1
我希望这有助于澄清我的问题。
解决方案
创建一个获取过去 12 个月提交票证列表的函数
ALTER FUNCTION func_isContributor(@dateFiled as DATE, @PersonID as INTEGER)
RETURNS INTEGER
AS
BEGIN
return
(SELECT
count(*)
FROM
tmp_tickets
WHERE
DateFiled BETWEEN DATEADD(month, -12, @dateFiled) and @dateFiled AND SubmittedBy = @PersonID)
END
然后检查此人是否有过去 12 个月的记录
; with cte as (
SELECT
SubmittedBy,
DateFiled,
isCounted = case when dbo.func_isContributor(DateFiled,SubmittedBy) -1 = 0 then 1 else 0 END
FROM
tmp_tickets
)
SELECT
lead.PersonID,
ContributorCount = Count(1),
PeriodMonth = MONTH(DateFiled),
PeriodYear = YEAR(DateFiled)
FROM tmp_assigned_lead lead
INNER JOIN cte
ON lead.AssignedPersonID = cte.SubmittedBy and cte.isCounted = 1
GROUP BY
lead.PersonID,
MONTH(DateFiled),
YEAR(DateFiled)
推荐阅读
- windows - 下载后自动打开 ZIP 文件内容
- database - 如何从我的数据库中返回所有行
- c# - 数据库连接抛出一些错误
- ios - 更改数据源时 UICollectionView 中的平滑动画
- string - 是否有一个简单的函数来制作一个字符列表的字符串?
- spring-boot - 有没有办法在 Spring Boot 2 Actuator 中禁用 ReactiveHealthIndicators?
- python - matplotlib 极坐标图刻度/轴标签位置
- powershell - 从 powershell 获取“特定时间”数组 (IIS) 的值
- clips - CLIPS - 我如何提示用户,直到他们输入有效的输入
- javascript - 添加和/或删除整个下拉选择列表