PL SQL按问题分组

时间:2018-10-18 17:57:08

标签: oracle plsql

我有两个表T1和T2。 T1具有作为序列生成的ID列。 它还有两个列,名字和姓氏。

表T2通过ID列(引用)连接到表T1。

T2表有一个薪金列,该列每隔几年会修订一次。

如果薪水已更改,我想获得所有的名字,姓氏,薪水和薪水日期。

我无法使用ID获取此信息。 如果员工上来审核,则会为同一对FN和LN对生成第二个ID。

例如:-

ID   FN    LN
1    John  Doe
2    John  Doe

ID   SALARY  DATE     
1    $1       2015     
2    $2       2018    

我正在尝试类似

SELECT T.FN ||'  '|| T.LN AS NAME, COUNT(*) AS CT, 
S.SALARY, S.DATE
SALARYTABLE S, EMP T
WHERE S.ID=T.ID 
HAVING COUNT(*) > 1
GROUP BY (T.FN ||'  '|| T.LN);

我已经通过使用Java程序解决了这个问题。我必须存储所有ID,并遍历所有记录,并检查FN和LN是否匹配,然后提取日期和薪水。这效率低下,我想在PL / SQL中完成。

请帮助。谢谢。

1 个答案:

答案 0 :(得分:1)

嗯,您的数据模型有点错误;您不应该依靠在人的名字上进行区分。如果又雇用了另一名“约翰·杜伊”怎么办?

无论如何:这样会吗?

  • CTE T1T2模拟您的表。我添加了更多行,只是为了确保 以下查询不会很明显地失败
  • INTER CTE将这两个表合并在一起,并使用LAG函数计算员工的先前工资
  • 最终查询从INTER中选择当前和以前薪水不同的行

由于已经有了这些表,因此将使用第16行。

SQL> with
  2    t1 (id, fn, ln) as
  3      (select 1, 'John', 'Doe' from dual union all
  4       select 2, 'John', 'Doe' from dual union all
  5       select 3, 'John', 'Doe' from dual union all
  6       select 5, 'Billy', 'Jean' from dual union all
  7       select 6, 'Billy', 'Jean' from dual
  8      ),
  9    t2 (id, salary, c_date) as
 10      (select 1, 1, 2015 from dual union all
 11       select 2, 2, 2018 from dual union all
 12       select 3, 2, 2019 from dual union all
 13       select 5, 3, 2016 from dual union all
 14       select 6, 3, 2017 from dual
 15      ),
 16  inter as
 17    (select
 18       t1.id, t1.fn, t1.ln,
 19       t2.id, t2.salary, t2.c_date,
 20       lag(t2.salary) over (partition by t1.fn, t1.ln
 21                            order by c_date) prev_salary
 22     from t1 join t2 on t1.id = t2.id
 23    )
 24  select i.fn, i.ln, i.salary, i.c_date
 25  from inter i
 26  where i.salary <> nvl(i.prev_salary, i.salary)
 27  order by i.ln, i.c_date;

FN    LN       SALARY     C_DATE
----- ---- ---------- ----------
John  Doe           2       2018

SQL>