MySQL Query用于选择单个ID中的下一行数据

时间:2018-03-05 20:55:36

标签: mysql

数据列是ID,数据和实际创建日期

以下是示例数据。

ID  Data        Actual Create Date
111 Open        2018-02-28
111 Comment     2018-02-28
111 Resolved    2018-03-01
222 Open        2018-03-02
222 Comment     2018-03-03
222 Resolved    2018-03-05

我需要做的是,在一个ID(EG.111)中,我需要创建一个名为结束日期的列,该列采用下一行的实际创建日期并使其成为上一个条目的结束日期,除非条目已解决,然后结束日期是创建日期。以便数据如下所示

ID  Data        Actual Create Date      End Date
111 Open        2018-02-28              2018-02-28
111 Comment     2018-02-28              2018-03-01
111 Resolved    2018-03-01              2018-03-01
222 Open        2018-03-02              2018-03-03
222 Comment     2018-03-03              2018-03-05
222 Resolved    2018-03-05              2018-03-05

显然我需要根据草莓

提供我目前运行的查询
SELECT a.IssueId AS ID, b.ShortId, a.Title AS Issue_Description, a.Request_Type, a.Site, b.Path, b.`Data`, b.`Actual Create Date`
FROM SIM_FE a
LEFT JOIN SIM_FE_Audit_Data b ON b.IssueId = a.IssueId
WHERE b.`Data` IN ('Open','Comment','Audit','Feasibility','Deep Dive','Scoping','Pending Others','Awaiting Requester Info','Resolved')
AND a.Request_Type LIKE '%Capacity:%'

它可以获取我需要的所有数据。没有唯一的密钥,因为数据是对发生的事情的审计跟踪。该ID对于项目是唯一的,但由于每个项目(ID列)在Data中显示多个内容,因此您将获得多个ID。短ID,问题描述,Request_Type,站点和路径都只是另一方面的数据可视化;它们可能在查询功能方面被排除在外,因为它们同样不是唯一的。

此查询的功能是基本上为流程中的每个步骤创建停止日期。目前,每个步骤只有一个开始日期(实际创建日期)。因此,能够将“下一步”的实际创建日期分配给上一步作为结束日期。我试过以我能想到的各种方式调整提出的答案,但它没有按预期工作。我使用基本查询从255行到超过143K。

这是我的下一次尝试:

SELECT a.IssueId AS ID, a.Title AS Issue_Description, a.Request_Type, a.Site, b.`Data`, b.`Actual Create Date`, b.`End Date`, b.rank
FROM SIM_FE a
LEFT JOIN (
    SELECT 
        IssueId, 
        `Data`, 
        `Actual Create Date`, 
        @rank:=CASE WHEN @id <> IssueId THEN 0 ELSE @rank+1 END AS rank,
        @id:=IssueId AS IssueId1,
        `End Date`
    FROM
        (SELECT @rank:=-1) r,
        (SELECT @id:= -1) i,
        (SELECT *
         FROM SIM_FE_Audit_Data
         WHERE `Data` IN ('Open','Comment','Audit','Feasibility','Deep Dive','Scoping','Pending Others','Awaiting Requester Info','Resolved')
         ORDER BY IssueId, `Actual Create Date`
        ) s
    INNER JOIN (
        SELECT
            IssueId AS ID2,
            `Actual Create Date` As `End Date`
        FROM
            SIM_FE_Audit_Data
    ) t ON t.ID2 = s.IssueId -1
) b ON b.IssueId = a.IssueId
WHERE Request_Type LIKE '%Capacity:%'

这个很奇怪,但基本上重复结束日期。导致255行变为39814行。所以,联接必须是错误的。

希望我正确地做了这个SQLFiddle

http://sqlfiddle.com/#!9/788b7/1

1 个答案:

答案 0 :(得分:0)

您可以做以下事情:

计算排名以获取每个ID的所有行的顺序。

SELECT t.id, t.data, t.create_date,
   @rank:=CASE WHEN @id <> id THEN 0 ELSE @rank+1 END AS rn,
   @id:=id AS idl
FROM
  (SELECT @rank:= -1) r,
  (SELECT @id:= -1) i,
  (SELECT *
   FROM mytable
   ORDER BY id, create_date
  ) t

然后使用唯一列自己连接此表并使用t1.id = t2.id + 1.这将为您提供除最后一个之外的所有匹配行,您可以使用CASE语句来获取原始日期。

如果您有任何疑问,请与我们联系。

修改

使用SQLFiddle之后,这里是更新的查询,它应该给出与问题中的结果类似的结果。

SELECT r1.id, r1.data, r1.create_date, r2.create_date END_DATE
FROM (SELECT t.id, t.data, t.create_date,
   @rank:=CASE WHEN @id <> id THEN 0 ELSE @rank+1 END AS rank,
   @id:=id AS idl
FROM
  (SELECT @rank:= -1) r,
  (SELECT @id:= -1) i,
  (SELECT *
   FROM Table1
   ORDER BY id, create_date
  ) t) r1 LEFT OUTER JOIN (SELECT t.id, t.data, t.create_date,
   @rank:=CASE WHEN @id <> id THEN 0 ELSE @rank+1 END AS rank,
   @id:=id AS idl
FROM
  (SELECT @rank:= -1) r,
  (SELECT @id:= -1) i,
  (SELECT *
   FROM Table1
   ORDER BY id, create_date
  ) t) r2 ON r1.rank = r2.rank - 1 AND r1.id = r2.id

您可以使用r1并将表连接两次,而不是为r2WITH重复相同的子查询。出于某种原因,SQLfiddle并不喜欢它,所以我这样做了。

http://sqlfiddle.com/#!9/ac311/7