如何在单个表中应用合并
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个表从上到下添加到单个表中