2016-07-26 9 views
0

Ich habe eine Menge von Google-Fu versucht, aber kann nicht ganz die Lösung, die ich suche. Die meisten sind einfach zu fortgeschritten für mein Szenario. Ich bin auch ein Newb mit SQL, also entschuldige ich mich für die Neuigkeit dieser Frage.SQL: Zurückgeben nur Zeilen mit Änderungen in einem Feld

Dies ist für Oracle 10g.

PS_JOB-Mitarbeiter haben eine eindeutige EMPLID, aber ihre FILE_NBR kann sich ändern. Ich muss den EMPLID jedes EE zurückgeben, der eine FILE_NBR Änderung hat. Dies ist ein kleiner Teil einer größeren Abfrage, die PS_JOB mit mehreren anderen Tabellen verbindet, also seien Sie bitte genau dort, wo die Lösung platziert werden soll: in der main SELECT-Anweisung, der Verknüpfung oder mit den anderen where-Klauseln.

Für eine einfache Tabelle Beispiel PS_JOB

EMPLID  FILE_NBR  Action Date 
0005   12345  Hire  01/01/2013 
0005   67890  term  04/05/2015 
0006   55555  Hire  02/05/2014 
0006   55555  term  04/15/2015 

Ich möchte EMPLID 0005 zurückkehren, da es eine FILE_NBR Änderung hat

ADDED EDIT: ich vermeiden wollte tun, dass als Zweck des gesamten Abfrage ist ein bisschen anders. Der Zweck der gesamten Abfrage ist EEs zurückzukehren, die einen Wert in b.rehire_dt haben, keinen Wert von REH in a.ACTION_REASON haben, und leisteten a.FILE_NBR Änderung für Ihre Hilfe

Select a.paygroup, a.EMPLID, a.FILE_NBR, c.name, e.TLM_STATUS, b.rehire_dt as "Emplmnt_Rltd_Dtes-Rehire Date", 
CASE 
WHEN a.ACTION_REASON = 'REH' THEN 'Y' 
ELSE 'N' 
END -- confirms if EE is true rehire 
FROM PS_EMPLOYMENT b --no effective dated rows 

right outer join SYSADM.PS_JOB a 
on a.emplid = b.emplid 

    right outer join SYSADM.PS_PERSONAL_DATA c -- no effective dated rows 
on a.emplid = c.emplid 

    right outer join SYSADM.PS_SMS_SUBSCRB_TBL d 
on a.paygroup = d.SUBSCRIBER_ID 

    right outer join PORTAL.PS_TS_EMPL_TLM_STATUS e 
on a.emplid = e.emplid 

    where 

b.rehire_dt IS NOT NULL 
    --and a.EFFDT = (select max (a2.effdt) from SYSADM.PS_JOB a2 where  
    a.EMPLID = a2.EMPLID) 
    and d.EFFDT = (select max (d2.effdt) from PS_SMS_SUBSCRB_TBL d2 where    
    d.SUBSCRIBER_ID = d2.SUBSCRIBER_ID) 
    and e.EFFDT = (select max (e2.effdt) from PORTAL.PS_TS_EMPL_TLM_STATUS e2  
    where e.emplid = e2.EMPLID) 
    and d.EFF_STATUS <> 'A' 
--and a.action <> 'REH' 
--and a.ACTION_REASON <> 'REH' 
    --and b.rehire_dt = a.EFFDT 
    --and b.emplid = '50731/246' 
    order by a.paygroup, a.emplid 

Dank haben !

Mit freundlichen Grüßen, Craig

LÖSUNG: Dank @Adam_Martin ich ziemlich einfach von Grund auf neu gestartet und verwendet Adams Fall Code in der select-Anweisung

SELECT distinct JOB.EMPLID, JOB.PAYGROUP, PER.NAME, EMP.REHIRE_DT as "Empl_Rlated_Dates_Rehire_Date", SUB.EFF_STATUS as "Paygroup Status",TLM.TLM_STATUS, 
CASE 
    WHEN JOB.ACTION_REASON = 'REH' THEN 'Y' 
    ELSE 'N' 
END as "True Rehire?", -- confirms if EE is true rehire 

CASE -------------------------------Adam's code 
    WHEN EXISTS(SELECT 1 
      FROM PS_JOB otherJobs 
      WHERE otherJobs.EMPLID = JOB.EMPLID 
      AND otherJobs.FILE_NBR <> JOB.FILE_NBR) THEN 'Y' 
ELSE 'N' 
END as "Had FN Change?" 

FROM SYSADM.PS_EMPLOYMENT EMP 

INNER JOIN SYSADM.PS_JOB JOB 
    ON EMP.EMPLID = JOB.EMPLID 

INNER JOIN SYSADM.PS_PERSONAL_DATA PER -- no effective dated rows 
    on JOB.emplid = PER.emplid 

    INNER JOIN SYSADM.PS_SMS_SUBSCRB_TBL SUB 
    on JOB.paygroup = SUB.SUBSCRIBER_ID 

    INNER JOIN PORTAL.PS_TS_EMPL_TLM_STATUS TLM 
    on JOB.emplid = TLM.emplid 

WHERE 
JOB.EMPLID = '50731/246' 
and EMP.REHIRE_DT IS NOT NULL 
and JOB.EFFDT = (select max (JOB2.effdt) from SYSADM.PS_JOB JOB2 where  
JOB.EMPLID = JOB2.EMPLID) 
and SUB.EFFDT = (select max (SUB2.effdt) from PS_SMS_SUBSCRB_TBL SUB2 where 
SUB.SUBSCRIBER_ID = SUB2.SUBSCRIBER_ID and SUB2.EFF_STATUS = 'A') 
+0

Bitte posten Sie Ihre aktuelle Abfrage. –

+0

Niemand wird verstehen, worüber Sie sprechen, wenn Sie keine Beispieltabellen/Abfragen anzeigen, um zu verstehen, wonach Sie fragen. Sie können nur Ihre Join und where/group by/have Klauseln posten, nicht die Auswahl. Sie müssen uns jedoch unbedingt einige Beispieltabellen geben. –

+0

Fertig .. Entschuldigung, dass! –

Antwort

1

Einige Bemerkungen; die meisten Leute benutzen LEFT JOIN s anstelle von RIGHT, weil sie sie leichter zu lesen finden. Es kann gut sein, diese Gewohnheit zu übernehmen. Verwenden Sie außerdem einen konsistenten Abstandsstil, damit Sie leicht lesen können, was Sie tun. Ich richte meine Keywords auf der einen Seite und meine Abfrage-Informationen auf der anderen Seite aus.

Diese Abfrage gibt Ihnen alle EMPLID, wo es mindestens zwei verschiedene FILE_NBR gibt.

Allerdings bin ich mir nicht sicher, wie Sie es in Ihre Abfrage integriert, das hängt davon ab, was Sie wollen. Wenn Sie nur auf Einträge mit Änderungen auswählen, werden Sie so etwas wie

AND EXISTS(SELECT 1 
      FROM PS_JOB otherJobs 
      WHERE otherJobs.EMPLID = a.EMPLID 
       AND otherJobs.FILE_NBR <> a.FILE_NBR) 

hinzufügen müssen, wenn Sie es nur in Ihrem wählen möchten, können Sie einfach ausgedrückt, dass in einem Fall Anweisung existiert, was auf die Existenz man jedoch wollen.

Zum Beispiel:

CASE 
    WHEN EXISTS(SELECT 1 
       FROM PS_JOB otherJobs 
       WHERE otherJobs.EMPLID = a.EMPLID 
       AND otherJobs.FILE_NBR <> a.FILE_NBR) THEN 'Y' 
    ELSE 'N' 
END 
+0

Komisch, ich wurde in einem anderen Thread für die Verwendung von linkem Join in derselben Abfrage angeschrien (andere Frage allerdings). –

+0

Wenn ich den Frageverlauf durchführe, sehe ich nur einen inneren Join, der ein äußerer Join sein sollte, kein linker Join. Standard Praxis ist Links Joins, denn das ist die Reihenfolge, in der wir es lesen und das ist was dbs implementieren. –

+0

Vielleicht könnte die Reihenfolge der Operationen helfen: Finde PS_JOB.EMPLID, die einen Wert in PS_EMPLOYMENT.REHIRE_DATE haben. Für diese EMPLIDs geben Sie ein Y/N zurück, wenn PS_JOB.FILE_NBR eine Änderung UND für die gleichen EMPLIDs gibt ein Y/N, wenn sie einen Wert von REH in PS_JOB.ACTION_REASON haben –

Verwandte Themen