查询以检索sql中多列中的更改

查询以检索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

我有下表和作业细节,如地点,组织,工作,等级等。 我想构建一个查询,以便只获取所有系统\人员\类型='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             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,以使其更易于理解到我的表的链接: