SQL 获取最新字段值

Posted

技术标签:

【中文标题】SQL 获取最新字段值【英文标题】:SQL to Get Latest Field Value 【发布时间】:2020-02-20 14:53:34 【问题描述】:

我正在尝试编写一个 SQL 查询 (SQL Server),它从历史记录表中返回一个字段的最新值。

表结构基本如下:

问题表:

issueid
10
20
30

更改组表:

changegroupid | issueid | updated    |
1             | 10      | 01/01/2020 |
2             | 10      | 02/01/2020 |
3             | 10      | 03/01/2020 |
4             | 20      | 05/01/2020 |
5             | 20      | 06/01/2020 |
6             | 20      | 07/01/2020 |
7             | 30      | 04/01/2020 |
8             | 30      | 05/01/2020 |
9             | 30      | 06/01/2020 |

变更表:

changegroupid | field   | newvalue |
1             | ONE     | 1        |
1             | TWO     | A        |
1             | THREE   | Z        |
2             | ONE     | J        |
2             | ONE     | K        |
2             | ONE     | L        |
3             | THREE   | K        |
3             | ONE     | 2        |
3             | ONE     | 1        | <--
4             | ONE     | 1A       |
5             | ONE     | 1B       |
6             | ONE     | 1C       | <--
7             | ONE     | 1D       |
8             | ONE     | 1E       |
9             | ONE     | 1F       | <--

预期结果:

issueid | updated    | newvalue
10      | 03/01/2020 | 1
20      | 07/01/2020 | 1C
30      | 06/01/2020 | 1F

因此,对问题项的每次更改都会创建 1 个更改组记录,其中包含更改日期,然后可以包含 1 个或多个更改项记录。

每个更改项都会显示已更改的字段名称和新值。

然后我需要将这些表链接在一起以获取每个问题、名为“ONE”的字段名称的最新值,以及最近更改的日期。

这些表来自 Jira,适合那些熟悉该表结构的人。

我一直在努力让它工作一段时间,到目前为止我有这个查询:

SELECT issuenum, MIN(created) AS updated FROM 
(
    SELECT ISSUE.IssueId, UpdGrp.Created as Created, UpdItm.NEWVALUE
    FROM ISSUE
        JOIN ChangeGroup UpdGrp ON (UpdGrp.IssueID = CR.ID)     
        JOIN CHANGEITEM UpdItm ON (UpdGrp.ID = UpdItm.groupid)        
    WHERE   UPPER(UpdItm.FIELD) = UPPER('ONE') 

) AS dummy
GROUP BY issuenum
ORDER BY issuenum

这将返回我正在寻找的前 2 列,但我正在努力解决如何返回最后一列,因为当我在第一行中包含该列时,我收到一条错误消息:“列在选择列表中无效因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句中。”

我已经在此处进行了搜索,但找不到与我的要求完全匹配的任何内容。

【问题讨论】:

用您正在使用的数据库标记您的问题。 。 . .旁注:ONE 已经大写。所以,UPPER() 是多余的。 【参考方案1】:

使用窗口函数:

SELECT i.*
FROM (SELECT i.IssueId, cg.Created as Created, ui.NEWVALUE,
             ROW_NUMBER() OVER (PARTITION BY i.IssueId ORDER BY cg.Created DESC) as seqnum
      FROM ISSUE i JOIN
           ChangeGroup cg
           ON cg.IssueID = CR.ID JOIN
           CHANGEITEM ci
           ON cg.ID = ci.groupid        
      WHERE UPPER(UpdItm.FIELD) = UPPER('ONE') 
    ) i
WHERE seqnum = 1
ORDER BY issueid;

【讨论】:

。 . .旁注:ONE 已经在 Upper 案例中。所以,UPPER() 是多余的。 @YogeshSharma 。 . .这是来自OP的代码。我的猜测是 'ONE' 确实是传入的参数或类似的东西。 这对我帮助很大,谢谢!是的,关于 UPPER('ONE') 是多余的,你是对的,但我在将查询简化为要放在此处的格式时错过了这一点。

以上是关于SQL 获取最新字段值的主要内容,如果未能解决你的问题,请参考以下文章

SQL 查询以获取每个位置的“最新”值

BigQuery:仅当字段具有特定值时才获取表中的最新行

SQL 获取具有与特定值匹配的最新关联的记录

复杂的 SQL 连接查询 - 获取最新行

SQL分组查询每个组的最新时间和上一个时间的某个字段值的差

SQL - 如何获取创建的同一日期的最新数据