【问题标题】:SQL select first row using cteSQL 使用 cte 选择第一行
【发布时间】:2018-07-03 16:50:06
【问题描述】:

我有如下的 sql 连接查询,它返回多行相同但列 paymentlineitem 不同。

DECLARE @fidelisInterestItems TABLE  (claim float,payment float,code varchar(50),interest money,paymentlineitem float);

INSERT INTO @fidelisInterestItems
Select 4250692,4104926,'T4535',2.04,9425737 Union All
Select 3677431,3685465,'L1820',2.63,8485100

CREATE TABLE #tmpReport(Claim int,HCPCS varchar(50),ClaimItem int,PaymentLineItem int,Interest money,Payment int)

Insert INTO #tmpReport
 Select P.Claim, ct.code, pl.claimItem, PL.PaymentLineItem,fi.Interest,P.Payment
FROM payment p with(nolock)
        JOIN paymentlineitem pl on p.payment=pl.payment 
        JOIN cpt ct on ct.cpt=pl.cpt 
        JOIN Eob e on e.eob=p.eob 
        JOIN Eobbatch eb on eb.eobbatch=e.eobbatch 
        JOIN @fidelisInterestItems fi on p.payment=fi.payment AND p.claim=fi.claim AND ct.code=fi.code 
        WHERE p.DisbursementDate IS NULL
SELECT * FROM #tmpReport
DROP TABLE #tmpReport

返回结果如下:

+---------+-------+-----------+-----------------+----------+---------+
|  Claim  | HCPCS | ClaimItem | PaymentLineItem | Interest | Payment |
+---------+-------+-----------+-----------------+----------+---------+
| 4250692 | T4535 |   5552227 |         9425733 |     2.04 | 4104926 |
| 3677431 | L1820 |   4151237 |         8485098 |     2.63 | 3685465 |
| 3677431 | L1820 |   4151238 |         8485099 |     2.63 | 3685465 |
+---------+-------+-----------+-----------------+----------+---------+

我想在哪里使用 cte 并在插入记录时只获取第一行。我确实尝试过使用 select top 1 但记录更多。 预期结果应该只有前两行,其中第三行有两条相同的记录,需要排除第二条记录。

插入时的预期结果应该只在#tmpReport 中插入这两个记录:

+---------+-------+-----------+-----------------+----------+---------+
|  Claim  | HCPCS | ClaimItem | PaymentLineItem | Interest | Payment |
+---------+-------+-----------+-----------------+----------+---------+
| 4250692 | T4535 |   5552227 |         9425733 |     2.04 | 4104926 |
| 3677431 | L1820 |   4151237 |         8485098 |     2.63 | 3685465 |
+---------+-------+-----------+-----------------+----------+---------+

【问题讨论】:

  • 这里似乎缺少一些信息。就像,除了一行之外,您想要的结果是什么,是否应该有某种顺序?此外,您构建的是一个临时表,而不是真正的公用表表达式 (CTE)。它们的工作方式相似,但不是一回事。
  • 当我们插入#tmpreport 时,它应该只插入前两行,因为我想在支付中占据前 1 行=3685465

标签: sql sql-server common-table-expression


【解决方案1】:

试试这个:

DECLARE @fidelisInterestItems TABLE  (claim float,payment float,code varchar(50),interest money,paymentlineitem float);

INSERT INTO @fidelisInterestItems
Select 4250692,4104926,'T4535',2.04,9425737 Union All
Select 3677431,3685465,'L1820',2.63,8485100

CREATE TABLE #tmpReport(Claim int,HCPCS varchar(50),ClaimItem int,PaymentLineItem int,Interest money,Payment int)

with cte as 
(
Select P.Claim, ct.code, pl.claimItem, PL.PaymentLineItem,fi.Interest,P.Payment, 
ROW_NUMBER() over (partition by P.Claim, ct.code order by (select null)) as ranking 
-- Include other columns in `partition by` which have to be equal to omit the next record
FROM payment p with(nolock)
        JOIN paymentlineitem pl on p.payment=pl.payment 
        JOIN cpt ct on ct.cpt=pl.cpt 
        JOIN Eob e on e.eob=p.eob 
        JOIN Eobbatch eb on eb.eobbatch=e.eobbatch 
        JOIN @fidelisInterestItems fi on p.payment=fi.payment AND p.claim=fi.claim AND ct.code=fi.code 
        WHERE p.DisbursementDate IS NULL
)
Insert INTO #tmpReport
Select * from cte where ranking = 1 
SELECT * FROM #tmpReport
DROP TABLE #tmpReport

【讨论】:

    【解决方案2】:

    你可以使用row_number():

    SELECT t.*
    FROM (SELECT t.*, row_number() over (partition by Claim, code, claimItem, Interest, Payment order by PaymentLineItem) as seqnum
          FROM #tmpReport t
         ) t
    WHERE seqnum = 1;
    

    或聚合:

    select Claim, code, claimItem, Interest, Payment, MIN(PaymentLineItem) as PaymentLineItem
    from #tmpReport t
    group by Claim, code, claimItem, Interest, Payment;
    

    【讨论】:

    • 我会给你第一次查询的分数。比WITH cte AS ( ...简洁多了。
    【解决方案3】:

    如果我正确理解了这个问题,这应该可以:

    DECLARE @fidelisInterestItems TABLE  (claim float,payment float,code varchar(50),
    interest money,paymentlineitem float);
    
    INSERT INTO @fidelisInterestItems
    Select 4250692,4104926,'T4535',2.04,9425737 Union All
    Select 3677431,3685465,'L1820',2.63,8485100
    
    CREATE TABLE #tmpReport(Claim int,HCPCS varchar(50),ClaimItem int,
    PaymentLineItem int,Interest money,Payment int)
    
    INSERT INTO #tmpReport
    SELECT P.Claim, ct.code, pl.claimItem, PL.PaymentLineItem,fi.Interest,P.Payment
    FROM payment p with(nolock)
            JOIN paymentlineitem pl on p.payment = pl.payment 
            JOIN cpt ct on ct.cpt = pl.cpt 
            JOIN Eob e on e.eob = p.eob 
            JOIN Eobbatch eb on eb.eobbatch = e.eobbatch 
            JOIN @fidelisInterestItems fi on p.payment = fi.payment 
                AND p.claim = fi.claim AND ct.code = fi.code 
            WHERE p.DisbursementDate IS NULL
                AND P.payment = 3685465
    
    SELECT TOP 1 * FROM #tmpReport
    
    DROP TABLE #tmpReport
    

    但是,我仍然不明白您对第一行的标准是什么,例如 ORDER BY pl.ClaimItem 或其他什么。但是,也许没关系?

    【讨论】:

    • 更新问题,我想要这样的结果。
    • 这里有太多的猜测工作,但看起来你需要一个GROUP BY P.payment 这里。但是,在不知道您要做什么的情况下,我无法真正进一步指导您。如果(例如)您正在寻找每列的 MIN,那么这可以实现您的目标。假设这是正确的,只需将 #tempReport 查询更改为 SELECT MIN(Claim) AS Claim, MIN(code) AS HCPCS, MIN(claimItem) AS claimItem, MIN(PaymentLineItem) AS PaymentLineItem, MIN(Interest) AS Interest, Payment FROM #tmpReport GROUP BY Payment。否则,你需要弄清楚你想如何分组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    • 2017-05-28
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    相关资源
    最近更新 更多