2016-07-29 20 views
0

Entschuldigung für den unklaren Titel.SQL Server - Mehrere Transaktions-IDs - Wenn enthalten - Nur Neueste auswählen

Ich versuche, einen Zeitüberprüfungsbericht in SQL zu erstellen, aber habe eine Wand getroffen.

Das Problem, mit dem ich konfrontiert bin, ist, dass manchmal Änderungen von Support-Mitarbeitern vorgenommen werden, nachdem ein Mitarbeiter seine Zeit eingereicht hat und die einzige Möglichkeit, diese zu unterscheiden, durch die Transaktions-ID ist. Wenn beispielsweise John Doe seine Zeitkarte übermittelt hat, wäre seine Transaktions-ID in der Tabelle 1234, aber wenn eine Änderung an diesem Eintrag vorgenommen würde, wäre die Transaktions-ID in der Tabelle 1234-00, dann 1234-01, dann 1234-02 und so weiter für jede Änderung. Was ich tun möchte, ist meine SQL-Abfrage ändern, so dass, wenn die Transaktions-ID enthält ein - es wählt nur den neuesten Eintrag.

Siehe folgende Beispielcode:

SELECT 
    jb_id AS JobID, 
    MAX(jb_nme) AS JobName, 
    MAX(emplye_nme_frst) + ' ' + MAX(emplye_nme_lst) AS FullName, 
    jchstry_dte_effctve AS EffectiveDate, 
    jchstry_hrs, 
    pytype_id PayType, 
    jbcstctgry_id, 
    jbcstctgry_dscrptn, 
    jchstry_srce_trnsctn_id 
FROM jb 
JOIN jbbllngitm 
    ON jbbllngitm.jb_rn = jb.jb_rn 
JOIN jbcstcde 
    ON jbcstcde.jb_rn = jb.jb_rn 
JOIN jchstry 
    ON jbcstcde.jbcstcde_rn = jchstry.jbcstcde_rn 
JOIN pytype 
    ON pytype.pytype_rn = jchstry.pytype_rn 
JOIN jbcstctgry 
    ON jbcstctgry.jbcstctgry_rn = jchstry.jbcstctgry_rn 
JOIN emplye 
    ON jchstry_rfrnce_rn = emplye.emplye_rn 
WHERE jb_id = '1234' 
AND jchstry_dte_effctve BETWEEN 'XXXX-04-01' AND 'XXXX-04-04' 
GROUP BY jbcstcde_nme, 
     jb.jb_rn, 
     jchstry.jchstry_dte_effctve, 
     jb.jb_id, 
     pytype.pytype_id, 
     jbcstctgry.jbcstctgry_id, 
     jbcstctgry.jbcstctgry_dscrptn, 
     jchstry.jchstry_hrs, 
     jchstry.jchstry_srce_trnsctn_id 

Beispieldaten

JobID JobName FullName EffectiveDate Hours PayType Source Transaction ID 
1234 XXXX John Doe 4/1/XXXX  0.25 Straight Time  5678 
1234 XXXX John Doe 4/1/XXXX  8  Straight Time  5678-01 
1234 XXXX John Doe 4/4/XXXX  8  Straight Time  4567 

Zum Beispiel in der obigen Tabelle, da es für 5678 zwei Transaktions-ID ist nur ich die Transaktions-ID auswählen möchten, dass die enthält -01. Wenn die Ergebnisse Transaktions-ID 5678-01, 5678-02 und 5678-03 hätten, möchte ich nur, dass die Abfrage diese Zeile mit 5678-03 zurückgibt.

Bitte lassen Sie mich wissen, wenn etwas unklar ist. Das war schwerer zu erklären als ich erwartet hatte.

+0

Setzen Sie die '01' in eine neue Spalte und Abfrage der Max für diese Spalte und Gruppe nach Transaktions-ID? – dfundako

+0

Aber es gibt Einträge, die überhaupt keine -01, -02 Werte haben. Die Transaktions-ID 4567 ist korrekt und es wurden keine Änderungen vorgenommen. –

+0

Gibt es eine Datumszeitstempelspalte, die den Zeitstempel nach jeder Änderung aufzeichnet? und welche Version von SQL-Server verwenden Sie? – objectNotFound

Antwort

0

Sie sind zu schlau und ich hatte Schwierigkeiten, Ihre Antworten zu folgen. Ich konnte es heute herausfinden. Hier ist, womit ich endete. Nochmals vielen Dank an alle für Ihre Hilfe.

With TimeVerifcation as (
select 
jb_id as JobID, 
max(jb_nme) as JobName, 
emplye_id as EmployeeID, 
max(emplye_nme_frst) + ' ' + max(emplye_nme_lst) as FullName, 
jbbllngitm_dscrptn as JobBillingItem, 
jchstry_dte_effctve as EffectiveDate, 
jchstry_hrs as Hours, 
max(pytype_id) PayType, 
jbcstctgry_id as CostCategoryID, 
jbcstctgry_dscrptn as CostCategoryDescription, 
row_number() over (partition by jbbllngitm_dscrptn,jchstry_dte_effctve,emplye_id,pytype_id order by jchstry_pstd_dte + ' ' + jchstry_pstd_tme desc) as RN 
from jb 
join jbcstcde on jbcstcde.jb_rn = jb.jb_rn 
join jchstry on jbcstcde.jbcstcde_rn = jchstry.jbcstcde_rn 
join pytype on pytype.pytype_rn = jchstry.pytype_rn 
join jbcstctgry on jbcstctgry.jbcstctgry_rn = jchstry.jbcstctgry_rn 
join emplye on jchstry_rfrnce_rn = emplye.emplye_rn 
join jbbllngitm on jbbllngitm.jbbllngitm_rn = jchstry.jbbllngitm_rn 
where jb_id = '72681-00' 
and emplye_nme_lst = 'Cortez' 
and jchstry_dte_effctve between '2016-04-01' and '2016-04-04' 
group by jchstry.jchstry_dte_effctve,jb.jb_id,jbcstctgry.jbcstctgry_id,jbcstctgry.jbcstctgry_dscrptn,jchstry.jchstry_hrs,jbbllngitm.jbbllngitm_dscrptn,emplye.emplye_id,pytype.pytype_id,jchstry.jchstry_pstd_dte,jchstry.jchstry_pstd_tme 
) 
Select * 
from TimeVerifcation 
where RN=1 
order by EffectiveDate 
1

Wenn es keine eindeutige ID-Spalte und keinen Zeitstempel des letzten Eintrags gibt, können Sie sich innerlich mit sich selbst verbinden. Hier sind die Ergebnisse, die Sie angegeben haben. Der innere Join entspricht der maximalen Transaktions-ID. Der Schlüssel hier ist, genügend Spalten auf dem Join einzufügen, um eindeutig zu sein, während Spalten ignoriert werden, die bearbeitet werden würden. Nicht elegant, aber weder ist nicht mit einem Zeitstempel oder einen eindeutigen ID-Spalte drop table #temp

SELECT 
1234 as JobID,'XXXX' as JobName,'John Doe' as FullName,'4/1/2016' as EffectiveDate,0.25 as Hours,'Straight' as PayType,'Time' as Source,'5678' as TransactionID 
INTO #temp 
UNION ALL 
SELECT 
1234,'XXXX','John Doe','4/1/2016',8,'Straight','Time','5678-01' 
UNION ALL 
SELECT 
1234,'XXXX','John Doe','4/4/2016',8,'Straight','Time','4567' 

SELECT * FROM #temp 

SELECT 
    t.JobID, t.JobName, t.FullName, t.EffectiveDate, t.Hours, t.PayType, t.Source, t.TransactionID 
FROM 
    #temp t 
INNER JOIN 
    (SELECT JobID, JobName, FullName, EffectiveDate, PayType, Source, MAX(TransactionID) TransactionID 
    FROM #temp 
    GROUP BY JobID, JobName, FullName, EffectiveDate, PayType, Source) t2 on 
    t2.JobID = t.JobID and 
    t2.JobName = t.JobName and 
    t2.FullName = t.FullName and 
    t2.EffectiveDate = t.EffectiveDate and 
    t2.PayType = t.PayType and 
    t2.Source = t.Source and 
    t2.TransactionID = t.TransactionID 
+0

Es gibt eine jchtry_id-Spalte sowie jchstry_pstd_tme –

1

ich es in SSMS testen, wie pro Ihren Antrag. Es funktioniert sehr gut. PS: Ich verwende temporäre Tabelle #test als die Tabelle mit der angegebenen Struktur und Daten. Bitte nehmen Sie die Änderung entsprechend vor. :)

-- Create table structure 
    create table #test(
     JobID int, 
     JobName varchar(10), 
     FullName varchar(50), 
     EffectiveDate date, 
     Hours money, 
     PayType varchar(10), 
     Source varchar(10), 
     TransactionID varchar(10) 
    ) 

--Insert Data into the temp table  
     insert #test 
     select 1234, 'XXXX', 'John Doe', '4/1/1990',  0.25, 'Straight', 'Time',  '5678' 
     union all 
     select 1234, 'XXXX', 'John Doe', '4/1/1990',  8, 'Straight', 'Time',  '5678-01' 
     union all 
     select 1234, 'XXXX', 'John Doe', '4/4/1990',  8, 'Straight', 'Time',  '4567' 
     union all 
     select 1234, 'XXXX', 'John Doe', '4/1/1990',  9, 'Straight', 'Time',  '5678-02' 
     union all 
     select 1234, 'XXXX', 'John Doe', '4/6/1990',  123, 'Straight', 'Time',  '5678-03' 
     union all 
     select 1234, 'XXXX', 'John Doe', '4/12/1990',  23, 'Straight', 'Time',  '5678-04' 


     insert #test 
     select 2345, 'XXXX', 'John Doe', '4/12/1990',  23, 'Straight', 'Time',  '2342' 
     union all 
     select 2345, 'XXXX', 'John Doe', '4/12/1990',  23, 'Straight', 'Time',  '2342-01' 

--Below is the solution for this question. 

     select jobid,jobname,fullname,effectivedate,hours,paytype,source,transactionid 
       from 
       (
        select *,max(a.orderbyid_in)over(partition by a.partitionid) as orderbyid_out 
        from 
        (
         select *, 
          (case when charindex('-',TransactionID) <> 0 then left(TransactionID,charindex('-',TransactionID)-1) 
            else TransactionID 
          end) as partitionid, 
          (case when charindex('-',TransactionID) <> 0 then right(TransactionID,charindex('-',reverse(TransactionID))-1) 
            else '00' 
          end) as orderbyid_in 
         from #test 

        ) as a 


       ) as b 
       where (transactionid = partitionid and orderbyid_out = '00') 
         or 
         (transactionid = partitionid +'-'+orderbyid_out) 
1

Hier ist, wie wir diese (Danke an @ Tanz-Henry für einen Teil der Testdaten, die ich geändert) lösen kann

create table #test 
    (
     JobID int, 
     JobName varchar(10), 
     FullName varchar(50), 
     EffectiveDate date, 
     Hours money, 
     PayType varchar(10), 
     Source varchar(10), 
     TransactionID varchar(10), 
     jchstry_id int, 
     jchstry_pstd_tme datetime 
    ) 

    delete #test 

--Insert Data into the temp table  
     insert #test 
     select 1234, 'XXXX', 'John Doe', '4/1/2016',  0.25, 'Straight', 'Time',  '5678' , 1, '4/1/2016 01:00:00' 
     union all 
     select 1234, 'XXXX', 'John Doe', '4/1/2016',  8, 'Straight', 'Time',  '5678-01' , 2, '4/1/2016 02:00:00' 
     union all 
     select 1234, 'XXXX', 'John Doe', '4/4/2016',  8, 'Straight', 'Time',  '4567' , 1 , '4/4/2016 03:00:00' 
     union all 
     select 1234, 'XXXX', 'John Doe', '4/1/2016',  9, 'Straight', 'Time',  '5678-02' , 3 , '4/1/2016 03:00:00' 
     union all 
     select 1234, 'XXXX', 'John Doe', '4/6/2016',  123, 'Straight', 'Time',  '5678-03' , 4, '4/6/2016 04:00:00' 
     union all 
     select 1234, 'XXXX', 'John Doe', '4/12/2016',  23, 'Straight', 'Time',  '5678-04' , 5, '4/12/2016 05:00:00' 
     union all 
     select 2345, 'XXXX', 'Mike Smith', '4/12/2016',  23, 'Straight', 'Time',  '2342' , 1 , '4/12/2016 03:00:00' 
     union all 
     select 2345, 'XXXX', 'Mike Smith', '4/12/2016',  23, 'Straight', 'Time',  '2342-01' , 2 , '4/12/2016 04:00:00' 

Abfrage:

Select * From 
(

select *, 
Left(TransactionID+'-', CHARINDEX('-',TransactionID+'-')) Lft, 
Rank() Over (Partition by FullName, Left(TransactionID+'-', CHARINDEX('-',TransactionID+'-')) Order By jchstry_id desc , jchstry_pstd_tme desc) as Rnk 
from #test 

) A Where Rnk =1 

Logik: Es sortiert die Zeilen nach FullName, Transaction_ID (bis zum Bindestrich) und der älteste Datensatz kommt auf Rang = 1, weil wir Orderin sind g von jchstry_id desc, jchstry_pstd_tme desc. Danach wählen wir nur diejenigen Datensätze aus, die Rnk = 1 haben.

Verwandte Themen