Oracle SQL使用标识符为成对的右左序列号创建相应的标签

时间:2016-11-16 16:21:53

标签: oracle

我正在尝试将左右部分与表格配对。我received an answer为一个非常相似的问题配对左侧部分,但我现在需要创建一个新列,说明相应的配对部分。

例如我有

ID  LR  Identifier
1   L   B15A
2   R   A15C
3   L   A15C
4   R   A15C
5   L   A15C
6   R   D5A2
9   R   D5A2
10  L   E5A6 
11  R   E5A6
12  L   E5A6
13  R   E5A6
14  R   H9S5
17  L   EE5A
18  R   EE5A

我需要查询返回

ID  LR  Identifier Counterhand Counterpart
2   R   A15C       L           3
3   L   A15C       R           2
4   R   A15C       L           5
5   L   A15C       R           4
10  L   E5A6       R           11
11  R   E5A6       L           10
12  L   E5A6       R           13
13  R   E5A6       L           12
17  L   EE5A       R           18
18  R   EE5A       L           17

上一个问题的链接是Here。 @mathguy非常有帮助地回答

2 个答案:

答案 0 :(得分:2)

继续以先前的答案为基础...... @mathguy做了很多努力,在看完亚历克斯的答案之后我认为他的表现更为紧凑,我使用了一个他不是的联盟,我们都使用了ROw_number和mod。

a = Proc.new do
  class A
    def initialize d
      @c = d
    end

    def print
     p @c #FIRST PRINT
    end
  end

  b = A.new(2)
  p b.print #SECOND PRINT
end

a.call

答案 1 :(得分:2)

您可以修改@mathguys以前的解决方案并检查每个结果是否是一对中的第一个或第二个:

mod(row_number() over (partition by identifier order by id), 2)

会给你0或1;然后你可以选择领先或延迟来获得上一个或下一个牌/ ID值:

case mod(row_number() over (partition by identifier order by id), 2)
  when 0 then lag(lr) over (partition by identifier order by id)
  else lead(lr) over (partition by identifier order by id) end as counterhand

公然复制和扩展@mathguy's previous code

with
     test_data ( id, lr, identifier ) as (
       select 001, 'L', 'B15A' from dual union all
       select 002, 'R', 'A15C' from dual union all
       select 003, 'L', 'A15C' from dual union all
       select 004, 'R', 'A15C' from dual union all
       select 005, 'L', 'A15C' from dual union all
       select 006, 'R', 'D5A2' from dual union all
       select 009, 'R', 'D5A2' from dual union all
       select 010, 'L', 'E5A6' from dual union all
       select 011, 'R', 'E5A6' from dual union all
       select 012, 'L', 'E5A6' from dual union all
       select 013, 'R', 'E5A6' from dual union all
       select 014, 'R', 'H9S5' from dual union all
       select 017, 'L', 'EE5A' from dual union all
       select 018, 'R', 'EE5A' from dual
     )
-- end of test data, the solution (SQL query) begins below this line
select id, lr, identifier,
  case mod(row_number() over (partition by identifier order by id), 2)
    when 0 then lag(lr) over (partition by identifier order by id)
    else lead(lr) over (partition by identifier order by id) end as counterhand,
  case mod(row_number() over (partition by identifier order by id), 2)
    when 0 then lag(id) over (partition by identifier order by id)
    else lead(id) over (partition by identifier order by id) end as counterpart
from ( select id, lr, identifier,
              row_number() over (partition by identifier, lr order by id) as rn,
              least( count(case when lr = 'L' then 1 end) over (partition by identifier),
                     count(case when lr = 'R' then 1 end) over (partition by identifier)
                   ) as least_count
       from   test_data
)
where rn <= least_count
order by id               --  ORDER BY is optional
;

给你:

        ID L IDEN C COUNTERPART
---------- - ---- - -----------
         2 R A15C L           3
         3 L A15C R           2
         4 R A15C L           5
         5 L A15C R           4
        10 L E5A6 R          11
        11 R E5A6 L          10
        12 L E5A6 R          13
        13 R E5A6 L          12
        17 L EE5A R          18
        18 R EE5A L          17

10 rows selected. 

同样的两个案例陈述可以添加到@ mathguy上一个答案的第二个版本中,并给出相同的结果。