Sql 需要帮助来编写查询吗

Sql 需要帮助来编写查询吗,sql,sql-server,date,sql-date-functions,Sql,Sql Server,Date,Sql Date Functions,我需要写一个查询,以获得分配给特定项目的任期 我有一个日常活动表,其中存储了公司中每个人的数据以及他们分配给项目的数据,格式如下 这显示员工E123每天在各种项目上的分配情况 未分配员工时,查询应返回开始日期和结束日期。 例如,在上述情况下,它应该返回 按项目分组只返回一条记录,开始日期为2019年6月21日,结束日期为2019年6月27日,有效期为7天,这是错误的 我试过这个: select EmpCode, ProjectId, min(Date), max(Date), count(E

我需要写一个查询,以获得分配给特定项目的任期

我有一个日常活动表,其中存储了公司中每个人的数据以及他们分配给项目的数据,格式如下

这显示员工E123每天在各种项目上的分配情况

未分配员工时,查询应返回开始日期和结束日期。 例如,在上述情况下,它应该返回

按项目分组只返回一条记录,开始日期为2019年6月21日,结束日期为2019年6月27日,有效期为7天,这是错误的

我试过这个:

select EmpCode, ProjectId, min(Date), max(Date), count(EmpCode)
where Date between cast('2019-04-01 00:00:00.000' as datetime) and getdate() --and s.ProjectId = 0
        and EmpId = 'E123'
group by EmpCode, ProjectId, Date

认为这就是你要寻找的:

DECLARE @Data TABLE
    (
    EmpId nVARCHAR(8),
    ProjectId nVARCHAR(3),
    Date DATE
    )

INSERT INTO @Data
(EmpId, ProjectId, Date)
VALUES
('EMP123', 'P1', '2019-06-18'),
('EMP123', 'P1', '2019-06-19'),
('EMP123', 'P1', '2019-06-20'),
('EMP123', NULL, '2019-06-21'),
('EMP123', NULL, '2019-06-22'),
('EMP123', NULL, '2019-06-23'),
('EMP123', 'P2', '2019-06-24'),
('EMP123', 'P2', '2019-06-25'),
('EMP123', NULL, '2019-06-26'),
('EMP123', NULL, '2019-06-27')

SELECT 
    MIN(d.Date) As StartDate,
    ISNULL(EndDate, MAX(Date)) As EndDate,
    DATEDIFF(d, MIN(d.Date), ISNULL(EndDate, MAX(Date))) + 1 As Tenure
FROM @Data d 
OUTER APPLY (SELECT TOP 1 DATEADD(d, -1, Date) As EndDate FROM @Data a WHERE a.EmpId = d.EmpId AND a.ProjectId IS NOT NULL AND a.Date > d.Date ORDER BY a.Date ASC) EndDate
WHERE
    d.ProjectId IS NULL
GROUP BY d.EmpId, d.ProjectId, EndDate
另一种(也是更常见的)方法是使用
行号和CTE创建孤岛(组)。这样可以避免对数据表进行第二次扫描。然后,您可以对员工和组进行分组,以获得最小值和最大值:

DECLARE @Data table (EmpId char(6),
                     ProjectId char(2),
                     [Date] date);

INSERT INTO @Data (EmpId,
                   ProjectId,
                   Date)
VALUES ('EMP123', 'P1', '2019-06-18'),
       ('EMP123', 'P1', '2019-06-19'),
       ('EMP123', 'P1', '2019-06-20'),
       ('EMP123', NULL, '2019-06-21'),
       ('EMP123', NULL, '2019-06-22'),
       ('EMP123', NULL, '2019-06-23'),
       ('EMP123', 'P2', '2019-06-24'),
       ('EMP123', 'P2', '2019-06-25'),
       ('EMP123', NULL, '2019-06-26'),
       ('EMP123', NULL, '2019-06-27');

WITH Grps AS (
    SELECT D.EmpId,
           D.ProjectId,
           D.[Date],
           ROW_NUMBER() OVER (PARTITION BY D.EmpId ORDER BY D.Date) -
           ROW_NUMBER() OVER (PARTITION BY D.EmpId, D.ProjectId ORDER BY D.Date) AS Grp
    FROM @Data D)
SELECT G.EmpId,
       MIN(G.[Date]) AS StartDate,
       MAX(G.[Date]) AS EndDate,
       DATEDIFF(DAY,MIN(G.[Date]),MAX(G.[Date]))+1 AS Tenure
FROM Grps G
WHERE G.ProjectId IS NULL
GROUP BY G.EmpId,
         G.Grp;

(感谢Koen Vissers提供可消费的样本数据。)

我觉得这是一个相对简单的聚合查询。唯一的挑战是确定群体

然而,这也很简单。它只是非空值的累积数
projectid
值:

select empid, min(date), max(date), count(*) as tenure
from (select d.*,
             count(projectid) over (partition by empid order by date) as grp
      from @data d
     ) d
where projectid is null
group by empid, grp
order by empid, min(date);
是一把小提琴。

试试这个>>

    SELECT EMP_PRO.EmpCode,
       EMP_PRO.ProjectId,
       Date_M.min_D StartDate,
       Date_M.max_D EndDate,
       Date_M.tenure
  FROM EMP_PRO
       LEFT OUTER JOIN
       (SELECT min (date) min_D, max (Date) max_D, count (Grp) tenure , ProjectId
          FROM (SELECT id,
                       ProjectId,
                       date,
                         DENSE_RANK () OVER (ORDER BY id)
                       - DENSE_RANK ()
                            OVER (PARTITION BY ProjectId ORDER BY id)
                          AS Grp
                  FROM EMP_PRO) T
        GROUP BY T.Grp ,ProjectId) Date_M
          ON EMP_PRO.date = Date_M.min_D
 WHERE Date_M.min_D IS NOT NULL AND EMP_PRO.ProjectId IS NULL

“我需要写一个查询来获得一个特定项目的任务期限。”太好了!谢谢你告诉我们,祝你好运。如果你被卡住了,那么请把你的帖子作为一个问题,并包括你的尝试,以便我们可以帮助你。如果你找到答案,那么也许考虑把它作为答案。@ Larnu,没有得到你。你对此有解决方案吗?这看起来像是@VnA的“差距和isnland”问题。不过,你在这里一个问题也没问过;我刚请求我们帮你解决这个问题。Stack Overflow不是一个免费的编码服务,它是一个针对编程问题的问答网站。如果你有一个问题(以“?”结尾),请通过编辑你的帖子来提问,但确保你在问题中展示了你的尝试,以便我们可以解释你的错误。谢谢。是的,我们有ans,但是首先你可以自己尝试任何东西,如果你在某个地方停留在你的查询中,请编辑这篇文章。正如我所说,我尝试了按项目分组(在原始问题中编辑),但这并没有让我在日期上分开,它会返回我的集体结果。你能给我一些建议吗?这正是我想要的。谢谢你的帮助@Koen。