我有一个存储票据请求的表,并记录请求和解决的日期。
我想制作一个查询,每周会显示系统中有多少未解决的故障单。
问题是如果我将请求的日期用作组标准,那么未解决超过一周的故障单不会被计算两次。我想确保任何未解决的票证超过我的团队规模,并根据需要多次提供其数量。
例如,使用以下数据:
id requested resolved
== ========== ==========
1 2015-07-01 2015-07-02
2 2015-07-01 NULL
3 2015-07-08 2015-07-10
4 2015-07-08 NULL
第一(26)和第二周(27)各有两个请求。每周有一个已解决的请求和一个未解决的请求,因此查询结果应显示第一周1未解析,第二周未解析2。 (未来一周内具有解决方案日期的项目也算作未解决,但出于简化此示例的目的,我只显示空日期。)
我希望结果显示:
year week # unresolved
==== ==== ============
2015 26 1
2015 27 2
到目前为止我的查询:
SELECT
YEAR(requested) `year`,
WEEK(requested, 5) `week`,
COUNT(id) `# unresolved`
FROM
tickets
WHERE
WEEK(requested) < WEEK(resolved)
OR resolved IS NULL
GROUP BY `Year`, `Week`;
每周仅显示1张未解决的票证:
year week # unresolved
==== ==== ============
2015 26 1
2015 27 1
我应该考虑什么来适当地修改此查询?
http://sqlfiddle.com/#!9/90782/1/0
修改
作为附加信息,这是一个相对简单的查询,为其提供任何特定的一周来检查:
SELECT
COUNT(id) `# unresolved`
FROM
tickets
WHERE
WEEK(requested) <= WEEK('2015-07-01')
AND
(
WEEK(resolved) > WEEK('2015-07-01')
OR resolved IS NULL
);
通过更改输入周,可以获得任何感兴趣的一周的未解决的门票数量。我的目标是创建一个查询,按周对所有可用数据进行分组,而不是修改此查询以获得单周结果。
答案 0 :(得分:1)
(注意:我正在展示我的思考过程,但您只需要在此答案中进行最终查询)
(注2:检查sqlfiddle here)
我会查看所请求的故障单并将故障单解决为两种不同类型的事件,所以
select requested eventDate, 1 ticketChange from table
会为每张请求的机票提供1个计数和
select resolved eventDate, -1 ticketChange from table
会给每个已解决的机票一个-1计数。如果我将这两个查询联合起来,我会得到一个日期列表,其中包含+1和-1,表示是否添加或解决了故障单。所以我每周都可以通过
获得一个未解决的问题 select year(eventDate) myYear, week(eventDate) myWeek, sum(ticketChange) totTicketChange
from (select requested eventDate, 1 ticketChange from table union all
select resolved eventDate, -1 ticketChange from table where resolved is not null)
group by year(eventDate) asc, week(eventDate) asc
但是既然你需要一个累计总数,那么我会定义一个变量@unresolvedCount并在我浏览选择行时递增它:
set @unresolvedCount := 0;
select myYear, myWeek, (@unresolvedCount := @unresolvedCount + totTicketChange) unresolved
from (select year(eventDate) myYear, week(eventDate) myWeek, sum(ticketChange) totTicketChange
from (select requested eventDate, 1 ticketChange from tickets union all
select resolved eventDate, -1 ticketChange from tickets where resolved is not null) TicketEvents
group by year(eventDate) asc, week(eventDate) asc) TicketCummulative
这正是您想要的。我已经用上面提到的小提琴检查了它,如果你能找到一个更有效的算法去做你想做的事情,我会感到惊讶。我还建议您自己运行每个内部查询,查看其结果,然后逐步解决问题。这将使您深入了解它的工作原理。
如果您希望仅在特定时间段(例如当前年份)获得结果,则根据您的需要,有三种不同的方法。如果您想要计算仅在此时间段内请求的门票,例如,您不想计算去年请求的门票,即使它们仍未解决或者即使他们今年得到解决,你也可以将最里面的查询改为:
select requested eventDate, 1 ticketChange from tickets where requested >= '2015-01-01' union all
select resolved eventDate, -1 ticketChange from tickets where requested >= '2015-01-01' and resolved is not null
如果您想要计算在给定时间段内请求或解决的故障单,那么您可以将最里面的查询更改为:
select requested eventDate, 1 ticketChange from tickets where requested >= '2015-01-01' union all
select resolved eventDate, -1 ticketChange from tickets where resolved is not null and resolved >= '2015-01-01'
如果您想计算所有门票,只要它们在当前时间段内被请求或解决,或者它们仍未解决(即使它们是3岁),那么您将不得不进行测试日期,在完整查询的最后,让内部查询处理所有票证。
... group by year(eventDate) asc, week(eventDate) asc) TicketCummulative where myYear >= 2015 and myWeek >= 1
答案 1 :(得分:0)
如何将Unresolved设置为MySQL,如下所示
set @preCount = 0;
select ticketsB.Year, ticketsB.Week,
IF(@preCount=0, @preCount:=Unresolved, @preCount:=@preCount+Unresolved) as Unresolved from (
SELECT
YEAR(requested) `Year`,
WEEK(requested, 5) `Week`,
count(id) `Unresolved`
FROM
tickets
WHERE
WEEK(requested) < WEEK(resolved)
OR resolved IS NULL
GROUP BY `Year`, `Week`) as ticketsB
在此处查看结果http://sqlfiddle.com/#!9/90782/61
基本上,您将先前未解决的计数存储到本地可验证的计数中,然后根据变量中的内容将未解析的计数添加到下一行。
答案 2 :(得分:0)
稀疏的数据集应该得到稀疏的答案,所以这是另一个想到的...
SELECT WEEK(x.requested) wk
, COUNT(y.id)
FROM tickets x
JOIN tickets y
ON y.id <= x.id
AND y.resolved IS NULL
WHERE x.resolved IS NULL
GROUP
BY WEEK(x.requested);
答案 3 :(得分:-1)
我认为这是一个透视问题。您需要将查询提供给报告日期/周。
SELECT
YEAR(requested) `Year`,
WEEK(requested, 5) `Week`,
COUNT(id) `Qty Unresolved`
FROM
tickets
WHERE
WEEK('2015-07-08') <= WEEK(resolved)
or resolved IS NULL
GROUP BY `Year`, `Week`;