Sql 选择表中的最新记录

Sql 选择表中的最新记录,sql,oracle,oracle11g,greatest-n-per-group,Sql,Oracle,Oracle11g,Greatest N Per Group,我有一个Oracle v11数据库,虽然我没有表的模式定义,但我已经在下面说明了我要实现的目标 这就是这张桌子的样子 我试图通过只选择最新的行来转换数据,该表保存更改的历史记录,我对更改不感兴趣,只对每个当前问题的最新值感兴趣 这就是我目前所拥有的 select issueno, case (when fieldname = 'name' then string_value end) name, case (when fieldname = 'point' then string_val

我有一个Oracle v11数据库,虽然我没有表的模式定义,但我已经在下面说明了我要实现的目标

这就是这张桌子的样子

我试图通过只选择最新的行来转换数据,该表保存更改的历史记录,我对更改不感兴趣,只对每个当前问题的最新值感兴趣

这就是我目前所拥有的

select issueno,
  case (when fieldname = 'name' then string_value end) name,
  case (when fieldname = 'point' then string_value end) point
from issues
where issueno = 1234

上面的查询的问题是它返回4行,我只想返回一行。

看看这样做是否有帮助;阅读代码中的注释

SQL> with issues (issueno, fieldname, string_value,
  2               transition_date, transition_id, load_date)
  3    as
  4    -- sample data; you have it in a table, don't type that
  5    (select 1234, 'name', null , date '2021-01-01', 1, date '2021-01-02' from dual union all
  6     select 1234, 'name', 'Tom', date '2021-02-11', 2, date '2021-02-12' from dual union all
  7     select 1234, 'point', '0' , date '2021-02-04', 3, date '2021-02-05' from dual union all
  8     select 1234, 'point', '5' , date '2021-02-10', 5, date '2021-02-11' from dual
  9    ),
 10  -- query you need begins here
 11  temp as
 12    -- rank values partitioned by ISSUENO and FIELDNAME, sorted by TRANSITION_ID
 13    (select issueno, fieldname, string_value,
 14       row_number() over (partition by issueno, fieldname
 15                          order by transition_id desc) rn
 16     from issues
 17    )
 18  select issueno,
 19    max(case when fieldname = 'name'  then string_value end) name,
 20    max(case when fieldname = 'point' then string_value end) point
 21  from temp
 22  where rn = 1
 23  group by issueno;

   ISSUENO NAME       POINT
---------- ---------- ----------
      1234 Tom        5

SQL>

看看这样做是否有帮助;阅读代码中的注释

SQL> with issues (issueno, fieldname, string_value,
  2               transition_date, transition_id, load_date)
  3    as
  4    -- sample data; you have it in a table, don't type that
  5    (select 1234, 'name', null , date '2021-01-01', 1, date '2021-01-02' from dual union all
  6     select 1234, 'name', 'Tom', date '2021-02-11', 2, date '2021-02-12' from dual union all
  7     select 1234, 'point', '0' , date '2021-02-04', 3, date '2021-02-05' from dual union all
  8     select 1234, 'point', '5' , date '2021-02-10', 5, date '2021-02-11' from dual
  9    ),
 10  -- query you need begins here
 11  temp as
 12    -- rank values partitioned by ISSUENO and FIELDNAME, sorted by TRANSITION_ID
 13    (select issueno, fieldname, string_value,
 14       row_number() over (partition by issueno, fieldname
 15                          order by transition_id desc) rn
 16     from issues
 17    )
 18  select issueno,
 19    max(case when fieldname = 'name'  then string_value end) name,
 20    max(case when fieldname = 'point' then string_value end) point
 21  from temp
 22  where rn = 1
 23  group by issueno;

   ISSUENO NAME       POINT
---------- ---------- ----------
      1234 Tom        5

SQL>

您可以通过使用
MAX()KEEP(..)
转换日期
的值(
)中的
LAST ORDER by
子句(或
load\u date
列,具体取决于您在查询中表示的替换)获取最新日期,例如

但是,如果相关日期值出现关系(相等值),则考虑使用<代码> DeNeSyRANK()/Case>函数,以计算返回等于<代码> 1 的值,连同 > RoxNoMulb()/Cyto>可以与主查询中的联接子句一起使用,如

WITH i AS
(
SELECT i.*,
       DENSE_RANK() OVER ( PARTITION BY issue_no, fieldname 
                               ORDER BY transition_date DESC) AS dr,
       ROW_NUMBER() OVER ( PARTITION BY issue_no, fieldname 
                               ORDER BY transition_date DESC) AS rn
  FROM issues i
)
SELECT i1.string_value AS name, i2.string_value AS point
  FROM ( SELECT string_value, rn FROM i WHERE dr = 1 AND fieldname = 'name'  ) i1
  FULL JOIN ( SELECT string_value, rn FROM i WHERE dr = 1 AND fieldname = 'point' ) i2
    ON i2.rn = i1.rn

您可以使用
MAX()KEEP(..)
值中的
LAST ORDER by
子句获取最新日期,该子句用于
transition\u date
(或
load\u date
列,具体取决于您在查询中表示的替换),例如

但是,如果相关日期值出现关系(相等值),则考虑使用<代码> DeNeSyRANK()/Case>函数,以计算返回等于<代码> 1 的值,连同 > RoxNoMulb()/Cyto>可以与主查询中的联接子句一起使用,如

WITH i AS
(
SELECT i.*,
       DENSE_RANK() OVER ( PARTITION BY issue_no, fieldname 
                               ORDER BY transition_date DESC) AS dr,
       ROW_NUMBER() OVER ( PARTITION BY issue_no, fieldname 
                               ORDER BY transition_date DESC) AS rn
  FROM issues i
)
SELECT i1.string_value AS name, i2.string_value AS point
  FROM ( SELECT string_value, rn FROM i WHERE dr = 1 AND fieldname = 'name'  ) i1
  FULL JOIN ( SELECT string_value, rn FROM i WHERE dr = 1 AND fieldname = 'point' ) i2
    ON i2.rn = i1.rn

假设您希望在列加载日期之前获得最新记录

select issueno,
  case (when fieldname = 'name' then string_value end) name,
  case (when fieldname = 'point' then string_value end) point
from issues
where issueno = 1234 and 
(fieldname , load_date) in (select fieldname ,max(load_date) from issues where issueno=1234 group by fieldname)

假设您希望在load_date列之前拥有最新记录

select issueno,
  case (when fieldname = 'name' then string_value end) name,
  case (when fieldname = 'point' then string_value end) point
from issues
where issueno = 1234 and 
(fieldname , load_date) in (select fieldname ,max(load_date) from issues where issueno=1234 group by fieldname)

我将使用子查询+窗口函数来实现您要求的功能(假设您使用的是基于load_date来确定最新记录)


语法([query\u partition\u子句]order\u by\u子句)实际上是一个窗口函数,它根据您在
[query\u partition\u子句]order\u by\u子句中声明规则的方式为每一行分配一个排序(假设您使用的是基于加载日期来确定最新记录)

([query\u partition\u子句]order\u by\u子句)
上的语法
ROW\u NUMBER()实际上是一个窗口函数,它为每一行分配一个排序,该排序由您在
[query\u partition\u子句]order\u by\u子句中声明规则的方式决定