簡體   English   中英

分區更改時將記錄分組並將行號作為奇數編號

[英]Grouping records and starting Row Number as a odd number when partition changes

請參閱下面的DDL:

create table Test (RevObjId int, LegalPartyId int, IsPrimary int)

insert into Test (RevObjId, LegalPartyId, IsPrimary) values (10, 20, 0)
insert into Test (RevObjId, LegalPartyId, IsPrimary) values (10, 21, 0)
insert into Test (RevObjId, LegalPartyId, IsPrimary) values (10, 22, 1)
insert into Test (RevObjId, LegalPartyId, IsPrimary) values (11, 20, 1)
insert into Test (RevObjId, LegalPartyId, IsPrimary) values (11, 21, 0)
insert into Test (RevObjId, LegalPartyId, IsPrimary) values (12, 30, 1)
insert into Test (RevObjId, LegalPartyId, IsPrimary) values (13, 40, 0)

我正在尋找下面的輸出:

RevObjId LegalPartyId IsPrimary RowNumber
10 22 1 1
10 20 0 2
10 21 0 3
11 20 1 5
11 21 0 6
12 30 1 7
13 40 0 9

當我使用以下查詢時:

select RevObjId, 
       LegalPartyId, 
       IsPrimary, 
       row_number() over(partition by RevObjId order by RevObjId asc,IsPrimary desc,LegalPartyId asc) as RowNumber 
       from test;

我按順序得到行號,每行遞增1,行號在分區改變后重置。 當分區(通過RevObjId)發生變化時,如何將行號更改為下一個奇數? 這是我的SQL小提琴http://sqlfiddle.com/#!6/01d5c/22

我們需要行號之間的差距,因為我需要以下列格式生成報告。 在此輸入圖像描述

這是我提出的一個支持問題: 如何在T-SQL中將每隔一行轉換為列?

對此的需求非常可疑,但我認為應該這樣做。

得到間隙的唯一時間是前一個分區的行數為奇數 - 然后間隙為1行。 因此,這將跟蹤具有奇數行的先前分區的運行計數,並將每個此類分區的行號總數加1。

WITH T
     AS (SELECT RevObjId,
                LegalPartyId,
                IsPrimary,
                odd_adj = CASE
                            WHEN RevObjId = LEAD(RevObjId) 
                                    OVER (ORDER BY RevObjId ASC, IsPrimary DESC, LegalPartyId ASC)
                              THEN 0
                            ELSE ROW_NUMBER() /*We are in the last row of the partition so can use rownumber as a more efficient alternative to count*/
                                    OVER (PARTITION BY RevObjId ORDER BY IsPrimary DESC, LegalPartyId ASC)%2
                          END,
                RowNumber = ROW_NUMBER() 
                                OVER(ORDER BY RevObjId ASC, IsPrimary DESC, LegalPartyId ASC)
         FROM   test)
SELECT RevObjId,
       LegalPartyId,
       IsPrimary,
       RowNumber
           +  SUM(odd_adj) OVER (ORDER BY RevObjId 
                                 ROWS UNBOUNDED PRECEDING) 
           - odd_adj AS RowNumber /*odd_adj is only potentially non zero for the last row in each partition 
                                   - if we are in the last row and it is 1 we need to deduct it 
                                     as this is not a previous partition */
FROM   T; 

SQL小提琴

嘗試如下

with groupcount as
(
  select RevObjId, (count(*) + 1)/ 2 * 2 as c
  from test
  group by RevObjId
), RevObjIdRN as
(
  select RevObjId, LegalPartyId, IsPrimary, 
         row_number() over (partition by RevObjId order by IsPrimary desc,LegalPartyId asc) as rn
  from test
)
select t2.RevObjId, t2.LegalPartyId, t2.IsPrimary, rn + relative
from (
  select RevObjId, sum(c) over (order by RevObjId) - c as relative
  from groupcount 
) t1  
join RevObjIdRN t2 on t1.RevObjId =  t2.RevObjId

sqlfiddle

解決方案基於以下部分:

with groupcount as
(
  select RevObjId, (count(*) + 1)/ 2 * 2 c
  from test
  group by RevObjId
)
select RevObjId, sum(c) over (order by RevObjId) - c as relative
from groupcount

它返回每組RevObjIdRevObjId偏移量)的起始row_number 其余的只是將每個RevObjId row_number()添加到此偏移量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM