Sql 在开始下一个任务之前,任务的总天数,按人员分组
我试图通过使用每个人的每个“任务登录”之间的日期来计算出如何显示某项任务已经完成了多少天。我认为这可以通过一个查询完成吗?我愿意接受建议和/或想法 下表:Sql 在开始下一个任务之前,任务的总天数,按人员分组,sql,sql-server,Sql,Sql Server,我试图通过使用每个人的每个“任务登录”之间的日期来计算出如何显示某项任务已经完成了多少天。我认为这可以通过一个查询完成吗?我愿意接受建议和/或想法 下表: --------+-----------+---------- Person | TaskLogin | Date --------+-----------+---------- Jane | A | 2013-01-01 Jane | B | 2013-01-03 Jane |
--------+-----------+----------
Person | TaskLogin | Date
--------+-----------+----------
Jane | A | 2013-01-01
Jane | B | 2013-01-03
Jane | A | 2013-01-06
Jane | B | 2013-01-10
Bob | A | 2013-01-01
Bob | A | 2013-01-06
---------------------------------------------------------------------
第1行:Jane从2013-01-01开始执行任务A,并一直执行到2013-01-03开始执行任务B=在任务A上执行了2天
第2行:Jane从2013-01-03开始执行任务B,一直执行到2013-01-06开始执行任务A=任务B工作了3天
第3行:Jane从2013-01-06开始执行任务A,一直执行到2013-01-10开始执行任务B=任务A工作了4天
第4行:跳过,因为这是Jane Jane可能完成或可能未完成任务B 2013-01-10的最长日期,但我们不会计算它
第5行:Bob从2013-01-01开始启动任务A,并在2013-01-06再次记录任务A,直到继续执行任务A为止=任务A已执行5天
第6行:跳过,因为这是Bob的最高日期
A=11天,因为2+4+5
B=3天,因为第2行
输出:
------+---------------------
Tasks | Time between Tasks
------+---------------------
A | 11 days
B | 3 days
**编辑:*****
Nicarus和Gordon Linoff的解决方案是2013年前的第一个解决方案,我在评论中进行了编辑。请注意,选择distinct*from table t for table可添加到Gordon Linoff的解决方案中,以适应有人在同一天登录两次的情况。您需要的是lead函数。这仅在SQL Server 2012中可用。在此之前,最简单的方法是关联子查询:
select TaskLogin, sum(datediff(day, date, nextdate)) as days
from (select t.*,
(select top 1 date
from table t2
where t2.person = t.person
order by date desc
) as nextdate
from table t
) t
where nextdate is not null
group by TaskLogin;
在SQL Server 2012中,它将是:
select TaskLogin, sum(datediff(day, date, nextdate)) as days
from (select t.*, lead(date) over (partition by person order by date) as nextdate
from table t
) t
where nextdate is not null
group by TaskLogin;
也许不是最优雅的方式,但它确实有效:
-- Setup table/insert values --
IF OBJECT_ID('TempDB.dbo.#TaskAccounting') IS NOT NULL BEGIN
DROP TABLE #TaskAccounting
END
CREATE TABLE #TaskAccounting
(
Person VARCHAR(4) NOT NULL,
TaskLogin CHAR(1) NOT NULL,
TaskDate DATETIME NOT NULL
)
INSERT INTO #TaskAccounting
VALUES ('Jane','A','2013-01-01')
INSERT INTO #TaskAccounting
VALUES ('Jane','B','2013-01-03')
INSERT INTO #TaskAccounting
VALUES ('Jane','A','2013-01-06')
INSERT INTO #TaskAccounting
VALUES ('Jane','B','2013-01-10')
INSERT INTO #TaskAccounting
VALUES ('Bob','A','2013-01-01')
INSERT INTO #TaskAccounting
VALUES ('Bob','A','2013-01-06');
-- Use a CTE to add sequence and join on it --
WITH Tasks AS (
SELECT
Person,
TaskLogin,
TaskDate,
ROW_NUMBER() OVER(PARTITION BY Person ORDER BY TaskDate) AS Sequence
FROM
#TaskAccounting
)
SELECT
a.TaskLogin AS Tasks,
CAST(SUM(DATEDIFF(DD,a.TaskDate,b.TaskDate)) AS VARCHAR) + ' days' AS TimeBetweenTasks
FROM
Tasks a
JOIN
Tasks b
ON (a.Person = b.Person)
AND (a.Sequence = b.Sequence - 1)
GROUP BY
a.TaskLogin
这实际上是可以做到的,但您应该先尝试一下分享您的尝试,您将获得所需的帮助。您希望减去任务A和/或B的日期。如何查找任务A的最早日期?你怎么找到最早的?提示:order by、count1或许多更好的查询。然后,您只需要找出日期的差异。@Fengson,减去任务的最早日期和最早日期并不能给出完整的结果,因为它们需要按人员分组,并且任务需要减去下一个任务登录名,而不一定是同一个任务。@Nicarus,谢谢。到目前为止,我已经有了datediff,我正试图找出如何获得下一个日期,并对其进行分组,以便它计算每个人之间的日期差异,然后通过taskLogin。您可以添加一个序列,然后加入该序列=序列+1并使用datediff。非常感谢。不幸的是,我的版本在2012年之前。第一次查询的结果似乎返回了18天(A)和7天(B),而不是11天和3天。然而,我认为这是正确的轨道,所以我会继续努力!另外,我不熟悉t.*和top 1,因此我将对它们进行一些研究。我调整了您的第一个代码以获得所需的结果。我会把它贴在下面。再次感谢![我无法在8小时内发布答案,但这是我最终使用的:]选择TaskLogin、sumdatediffday、theDate、nextDate作为天,从选择t.*,从日志t2中选择MINt2.theDate,其中t.theDate