如何在单个表中应用合并

Posted

技术标签:

【中文标题】如何在单个表中应用合并【英文标题】:How to apply merge in single table 【发布时间】:2019-09-05 10:09:58 【问题描述】:

我想使用合并更新我的表。因此,当员工加入另一家公司时,其新的(加入日期)将在他之前的条目中更新为(退出日期)。约束(((there is no unique id and name)))(((sno, ename, dept, comp, doj, doe))) 这些是表emp中的属性。

这是我必须更新的表。

Sno ENAME   COMP    DEPT    DOJ         DOE 
-----------------------------------------------
1   rock    mi      it  10-AUG-18    -  
2   dock    apple   it  12-AUG-18    -  
3   rock    google  it  01-AUG-70    -  
4   dock    samsung it  26-AUG-89    -  

应用合并后它应该是这样的。

Sno ENAME   COMP    DEPT    DOJ         DOE 
-----------------------------------------------
1   rock    mi      it  10-AUG-18    01-AUG-70  
2   dock    apple   it  12-AUG-18    26-AUG-89  
3   rock    google  it  01-AUG-70    -  
4   dock    samsung it  26-AUG-89    -

【问题讨论】:

【参考方案1】:

您可以将合并与子查询一起使用:

merge into t using
      (select t.*, lead(doj) over (partition by ename order by doj) as next_doj
       from t
      ) tt
      on tt.sno = t.sno and tt.next_doj is not null
when matched then update
    set doe = next_doj;

您也可以使用子查询和update 来表达这一点:

update t
    set doe = (select min(t2.doe)
               from t tt
               where tt.ename = t.ename and
                     tt.doe > t.doe
              );

【讨论】:

如果我必须使用源表和目标表使用合并。 最初目标表为空的地方 @TanmaySwami 。 . .你会有不同的问题,insert 会更合适。 MERGE INTO emp1 x USING (SELECT empno, ename, company, dept, doj, doe, valid FROM emp) y ON (x.enmae = y.ename) WHEN MATCHED THEN UPDATE emp M1 SET M1 .doe = (SELECT doj FROM (SELECT M2.doj, ROW_NUMBER() OVER (PARTITION BY M2.ename ORDER BY M2.doj DESC) AS RN FROM emp M2 WHERE M1.ename = M2.ename AND M1.company M2 .company AND M2.doj > M1.doj ) WHERE RN = 1) - 1 WHEN NOT MATCHED THEN INSERT(empno, ename, company, dept, doj, doe, valid) VALUES(y.empno, y.ename, y.公司,y.dept,y.doj,y.doe,y.valid); --------我在匹配语句时遇到问题。 @TanmaySwami 。 . . merge 与此答案中的内容有些不同。也许你应该问一个新问题。【参考方案2】:

您可以使用update 语句,包括select 语句和with..as 子句,其中包含lag() over (..)max() over (..) 分析函数,其结果将用作嵌套select 语句的匹配条件.

update tab t2
   set t2.doe = ( with t1 as ( 
                         select t.*, 
                                lag(doj) over (partition by ename order by doj) as lg_doj,
                                max(doj) over (partition by ename order by doj) as mx_doj
                           from tab t
                    )  
                    select lg_doj
                      from t1
                     where t1.ename = t2.ename
                       and t1.mx_doj = t2.doj 
                     ); 

Demo

但不适合通过员工姓名跟踪员工,您应该使用员工 ID。

【讨论】:

【参考方案3】:

这种情况下你可以直接使用update,因为这种情况下merge语句可能会出现问题。

UPDATE MYTABLE M1
SET M1.DOE = (SELECT DOJ FROM (SELECT M2.DOJ, 
ROW_NUMBER() OVER (PARTITION BY M2.ENAME ORDER BY M2.DOJ) AS RN 
FROM MYTABLE M2 
WHERE M1.ENAME = M2.ENAME
AND M1.COMP <> M2.COMP
AND M2.DOJ < M1.DOJ
) WHERE RN = 1)

此外,您可以在 UPDATE 语句中使用 WHERE 子句来限制没有更改其工作的记录或第一个工作的记录,以避免使用空值进行不必要的更新。

干杯!!

【讨论】:

根据您的代码,新的 doj 在所有现有 doe 中更新(对于相同的员工姓名) Sno ENAME COMP DEPT DOJ DOE 1 rock mi it 10-AUG-18 01-AUG-70 2 rock apple it 12-AUG-18 01-AUG-70 3 rock google it 01-AUG-70 - 它应该更新为 Sno ENAME COMP DEPT DOJ DOE 1 rock mi it 10-AUG-18 12-AUG-18 2 rock apple它 12-AUG-18 01-AUG-70 3 摇滚谷歌它 01-AUG-70 - 从 ORDER BY 中删除 DESC 并将 > 更改为 根据上面的评论更新了答案。

以上是关于如何在单个表中应用合并的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Java中的PDFPTable将2个表从上到下添加到单个表中

如何在单个合并语句中执行多个更新

如何在火花中合并或连接具有不相等列号的数据框

Office表中如何把一定范围单元格的内容多列数据去除空值以TXT文本方式导出?

我如何在这里将两个模板视图合并到单个视图中?

我们如何在反应原生项目中将多个图像合并为单个图像