Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何获取列上上次更新的行_Sql_Oracle_Window Functions - Fatal编程技术网

Sql 如何获取列上上次更新的行

Sql 如何获取列上上次更新的行,sql,oracle,window-functions,Sql,Oracle,Window Functions,目标: 对于每个IDCONT,我需要获取状态ID的最后更改/更新的日期 例如: with reftable as ( select 1 as PROCESSID, 'A' as IDCONT, 'X' as STATEID, '10' AS DAY_ID union all select 2 as PROCESSID, 'A' as IDCONT, 'X' as STATEID, '11' AS DAY_ID union all select 3 as PROCESSID, 'A' as

目标: 对于每个IDCONT,我需要获取状态ID的最后更改/更新的日期

例如:

with reftable as (
 select 1 as PROCESSID, 'A' as IDCONT, 'X' as STATEID, '10' AS DAY_ID union all
 select 2 as PROCESSID, 'A' as IDCONT, 'X' as STATEID, '11' AS DAY_ID union all
 select 3 as PROCESSID, 'A' as IDCONT, 'Y' as STATEID, '12' AS DAY_ID union all
 select 4 as PROCESSID, 'A' as IDCONT, 'Y' as STATEID, '13' AS DAY_ID union all

 select 1 as PROCESSID, 'B' as IDCONT, 'N' as STATEID, '14' AS DAY_ID union all
 select 2 as PROCESSID, 'B' as IDCONT, 'N' as STATEID, '15' AS DAY_ID union all
 select 3 as PROCESSID, 'B' as IDCONT, 'M' as STATEID, '16' AS DAY_ID union all

 select 1 as PROCESSID, 'C' as IDCONT, 'X' as STATEID, '11' AS DAY_ID union all
 select 2 as PROCESSID, 'C' as IDCONT, 'X' as STATEID, '18' AS DAY_ID union all
) ...
预期结果:

PROCESSID   IDCONT   STATID   DAYID
3           A        Y        12
2           B        N        15
1           C        X        11        
我解决了这个问题:

...
SELECT IDCONT, STATEID, MIN(DAY_ID)
FROM REFTABLE 
WHERE (IDCONT, STATEID) IN (
   SELECT IDCONT, FIRST_VALUE(STATEID) OVER PARTITION BY IDCONT ORDER BY PROCESSID DESC) AS STATEID
   FROM REFTABLE
)
但是我想做同样的事情,而不需要第二次叫桌子


谢谢

使用FIRST_值确实会给您带来变化,但是您能相信表中只有一个变化吗?其他更改是否会使其无效并导致错误数据

我使用了LAG函数,但是它没有返回IDCONT C,因为它没有变化

使用CTE获取数据,然后使用查询进行筛选可能会更快,因为不能在where子句中放入LAG或FIRST_值。这将防止再次访问数据库

CREATE TABLE REFTABLE
    ([PROCESSID] int, [IDCONT] varchar(1), [STATEID] varchar(1), [DAY_ID] int)
;

INSERT INTO REFTABLE
    ([PROCESSID], [IDCONT], [STATEID], [DAY_ID])
VALUES
    (1, 'A', 'X', 10),
    (2, 'A', 'X', 11),
    (3, 'A', 'Y', 12),
    (4, 'A', 'Y', 13),
    (1, 'B', 'N', 14),
    (2, 'B', 'N', 15),
    (3, 'B', 'M', 16),
    (1, 'C', 'X', 11),
    (2, 'C', 'X', 18)
;

with chgfound as (SELECT TOP 100 PERCENT PROCESSID, IDCONT, STATEID, DAY_ID, LAG(STATEID) OVER(PARTITION BY IDCONT ORDER BY IDCONT, PROCESSID) as LastState
from REFTABLE
order by IDCONT, PROCESSID
)
select * from chgfound where STATEID !=LastState

还注意到你有甲骨文标签。我是在SQL Server中这样做的,但它必须非常接近于相同的值。

如果不需要返回STATEID未更改的IDCONT,它将是一个C。一个REFTABLE trip可能如下所示;看看它在现实中是否有任何好处

这里有一种方法:

select r.*
from (select r.*,
             lag(stateid) over (partition by idcont order by day_id) as prev_stateid,
             first_value(stateid) over (partition by idcont order by day_id desc) as last_stateid
      from reftable r
     ) r
where stateid = last_stateid and (prev_stateid is null or prev_stateid <> stateid);

但是,这不处理状态更改回以前状态的情况。如果有必要,可以添加这种逻辑。

看看这个问题,它有点不同,但我认为是相同的模式。您的SQL不起作用。在其他问题中,REFTABLE定义中没有DUAL,它首先抛出一个无效的关系运算符错误。\u VALUESTATEID。此外,对于PROCESSID=2和IDCONT=B,我认为STATEID的值为'M'而不是'N'。比如说为什么是15岁?如果数据发生变化怎么办?你选择哪个X?
select r.*
from (select r.*,
             lag(stateid) over (partition by idcont order by day_id) as prev_stateid,
             first_value(stateid) over (partition by idcont order by day_id desc) as last_stateid
      from reftable r
     ) r
where stateid = last_stateid and (prev_stateid is null or prev_stateid <> stateid);