SQL Server - 多个交易ID' s - 如果包含 - 仅选择最新

时间:2016-07-29 18:44:21

标签: sql-server tsql

道歉标题不清楚。

我正在尝试在SQL中创建一个时间验证报告但是已经碰壁了。

我面临的问题是,在员工提交时间后,支持人员有时会进行更改,而区分这些更改的唯一方法是使用交易ID。例如,如果John Doe提交了他的时间卡,他在表中的交易ID将是1234但是如果对该条目进行了更改,则表中的交易ID将是1234-00然后是1234-01然后是1234-02,依此类推每次改变。我想要做的是改变我的SQL查询,以便如果交易ID包含 - 它只选择最新的条目。

请参阅下面的示例代码:

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

示例数据集

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

例如,在上表中,由于5678有两个交易ID,我只想选择包含-01的交易ID。如果结果具有事务ID 5678-01,5678-02和5678-03,我只希望查询返回5678-03的那一行。

如果有任何不清楚的地方,请告诉我。这比我预想的更难解释。

4 个答案:

答案 0 :(得分:1)

如果没有唯一的ID列,并且没有最后一个条目的时间戳,则可以内部连接到自身。以下是您提供的结果。内部联接是最大事务ID。这里的关键是在连接上包含足够的列是唯一的,同时忽略要编辑的列。不优雅,但两者都没有时间戳或唯一ID列 删除表#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

答案 1 :(得分:1)

我根据您的要求在SSMS中测试它。它工作得很好。 PS:我使用临时表#test作为具有给定结构和数据的表。请适当地进行修改。 :)

-- 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)

答案 2 :(得分:1)

以下是我们如何解决这个问题(感谢@ Dance-Henry对我修改过的一些测试数据)

   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'

<强>查询:

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

逻辑:按FullName,Transaction_ID(按破折号)对行进行排名,最旧的记录按等级= 1排序,因为我们按jchstry_id desc,jchstry_pstd_tme desc排序。之后,我们只选择那些Rnk = 1的记录。

答案 3 :(得分:0)

你们太聪明了,我无法回答你的问题。我今天能够搞清楚。这就是我最终的结果。再次感谢所有人的帮助。

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