查询以检索sql中多列中的更改
我有下表和作业细节,如地点,组织,工作,等级等。 我想构建一个查询,以便只获取所有系统\人员\类型='EMP'的位置、组织中的更改查询以检索sql中多列中的更改,sql,oracle,Sql,Oracle,我有下表和作业细节,如地点,组织,工作,等级等。 我想构建一个查询,以便只获取所有系统\人员\类型='EMP'的位置、组织中的更改 per_assignments Person_id locat_id org_id job_id grade_id system_person_type START_DT END_DT 1 Toronto XYZ 1 GR1
per_assignments
Person_id locat_id org_id job_id grade_id system_person_type START_DT END_DT
1 Toronto XYZ 1 GR1 EMP 01-JAN-2019 20-JAN-2019
1 US XYZ 1 GR1 EMP 21-JAN-2019 31-DEC-4712
2 Chicago ABC 2 GR1 EX-EMP 01-jul-2017 30-Nov-2017
2 Toronto XYZ 3 GR2 EMP 01-JAN-2019 03-JUL-2019
2 India GFH 3 GR2 EMP 04-JUL-2019 08-SEP-2019
2 India GFH 4 GR2 EMP 09-SEP-2019 31-DEC-4712
因此,在上述示例中,输出应为:
person_id old_locat_id new_locat_id old_org_id new_org_id old_start_dt new_start_dat
1 Toronto US - - 01-jan-2019 21-jan-2019
2 Toronto India XYZ GFH 01-JAN-2019 04-JUL-2019
我创建了下面的查询,但是从下面的查询中,我得到了旧的\u start\u dt>新的\u start\u dt,并且没有得到所需的所有更改,
仅检索到1个列更改。如何更改以下查询以满足上述要求
SELECT DISTINCT paam_change_loc.person_id ,
to_char(paam_change1.start_date,'YYYY-MM-DD') AS old_effective_start_dt ,
to_char(paam_change_loc.start_date,'YYYY-MM-DD') AS new_effective_start_dt ,
paam_change1.location_id AS old_loc_value ,
paam_change_loc.location_id AS new_loc_value
FROM per_assignments paam_change_loc,
per_assignments paam_change1
WHERE paam_change_loc.person_id =paam_change1.person_id
AND (
paam_change_loc.location_id IS NOT NULL
AND paam_change_loc.location_id <> paam_change1.location_id )
AND paam_change_loc.system_person_type = 'EMP'
AND paam_change1.system_person_type = 'EMP'
AND to_char(to_date(paam_change_loc.start_date),'DD-MM-YYYY') BETWEEN ('05-08-2019') AND '05-12-2019'
AND (
to_char(to_date(paam_change_loc.start_date)-1,'DD-MM-YYYY') BETWEEN ('05-08-2019') AND '05-12-2019' )
“05-08-2019”和“05-12-2019”是将传递到查询的传输日期,并且将在这两个日期之间比较日期我不确定数据库的数据结构。将样本数据视为表格,您可以使用分析功能实现预期输出:
Select person_id,
Locat_id as old_locat_id,
New_locat_id,
org_id as old_org_id,
New_org_id,
Start_date as old_start_date,
New_start_date
From
(Select t.*,
Lead(org_id) over (partition by person_id order by start_date) as new_org_id,
Lead(start_date) over (partition by person_id order by start_date) as new_start_date,
Lead(locat_id) over (partition by person_id order by start_date) as new_locat_id,
From your_table t where system_person_type = 'EMP')
Where locat_id <> new_locat_id or org_id <> new_org_id;
干杯 此查询提供了预期结果:
select person_id, prev_start_dt, start_dt,
case loc_new when loc_old then ' - ' else loc_old end loc_old,
case loc_new when loc_old then ' - ' else loc_new end loc_new,
case org_new when org_old then ' - ' else org_old end org_old,
case org_new when org_old then ' - ' else org_new end org_new
from (
select person_id, locat_id loc_new, org_id org_new, start_dt,
lag(locat_id) over (partition by person_id order by start_dt) loc_old,
lag(org_id) over (partition by person_id order by start_dt) org_old,
lag(start_dt) over (partition by person_id order by start_dt) prev_start_dt,
case start_dt when 1 + lag(end_dt) over (partition by person_id order by start_dt)
then 1 end flag
from per_assignments)
where flag = 1 and (loc_new <> loc_old or org_new <> org_old)
在内部查询中,根据需要为系统\人员\类型和日期应用过滤器。首先,我使用了三次lag,并且在列标志中标记连续行。然后仅显示位置或组织已更改的标记行。此查询不起作用。它在旧组织id和新组织id列中提供相同的id。我们还必须传递开始日期和结束日期。不确定lead函数是否有助于解决这种情况,这将给出一个错误-ORA-00932:不一致的数据类型:预期的CHAR Get NUMBER,因为它在Date上有一个滞后函数如果您将日期存储为字符串,您会发现这是多么糟糕的做法,您无法对其进行操作。如果不使用to_date,我会更改此列的类型。如果您的日期是日期类型,请使用tool.ribbons显示您的查询-非常抱歉。直到现在才意识到我的错误。组织id、位置id是数字数据类型。我已经对您刚才共享的链接进行了更改。该查询给出了相同的错误。我将org id和loc id写为char,以使其更易于理解到我的表的链接: