繁体   English   中英

SQL 在同一个表上选择两个相同的列但具有不同的 ORDER

[英]SQL select two same column on same table but with different ORDER

实习生来了我需要从同一个表中创建一个姓氏列表。

假设我们有一个名为“sample”的表,该表仅包含:

在此处输入图片说明

我想在这里做的是将选择姓氏列,但顺序不同,第一列升序,第二列降序,如下图所示

在此处输入图片说明

这是一个选项:它将名字和姓氏拆分为两个使用row_number分析函数的子查询。 然后它用于join行。

第 1 - 6 行代表您的样本数据。 您真正需要的查询从第 7 行开始。

SQL> with test (last_name, first_name) as
  2    (select 'L1one'  , 'F1one'    from dual union all
  3     select 'L2two'  , 'F2two'    from dual union all
  4     select 'L3three', 'F3hthree' from dual union all
  5     select 'L4four' , 'F4four'   from dual
  6    ),
  7  ln as
  8    (select last_name,
  9       row_Number() over (order by last_name) rn
 10     from test
 11    ),
 12  fn as
 13    (select first_name,
 14       row_number() over (order by first_name desc) rn
 15     from test
 16    )
 17  select l.last_name, f.first_name
 18  from ln l join fn f on f.rn = l.rn
 19  order by l.last_name
 20  /

LAST_NA FIRST_NA
------- --------
L1one   F4four
L2two   F3hthree
L3three F2two
L4four  F1one

SQL>

[编辑:两个姓氏? 我还以为是笔误]

如果是这样,自加入是更好的选择:

SQL> with test (last_name, first_name) as
  2    (select 'L1one'  , 'F1one'    from dual union all
  3     select 'L2two'  , 'F2two'    from dual union all
  4     select 'L3three', 'F3hthree' from dual union all
  5     select 'L4four' , 'F4four'   from dual
  6    ),
  7  temp as
  8    (select last_name,
  9       row_number() over (order by last_name asc) rna,
 10       row_number() over (order by last_name desc) rnd
 11     from test
 12    )
 13  select a.last_name, d.last_name
 14  from temp a join temp d on a.rna = d.rnd
 15  order by a.last_name;

LAST_NA LAST_NA
------- -------
L1one   L4four
L2two   L3three
L3three L2two
L4four  L1one

SQL>

这是一种方法。 在单个子查询中,根据升序分配序数 ( rn ),但也要跟踪总行数。 然后跟着加入。

with
  test (last_name, first_name) as (
    select 'L1one'  , 'F1one'    from dual union all
    select 'L2two'  , 'F2two'    from dual union all
    select 'L3three', 'F3hthree' from dual union all
    select 'L4four' , 'F4four'   from dual
   )
, prep (last_name, rn, ct) as (
    select last_name, row_number() over (order by last_name), count(*) over ()
    from   test
  )
select a.last_name as last_name_asc, b.last_name as last_name_desc
from   prep a inner join prep b on a.rn + b.rn = a.ct + 1
;


LAST_NAME_ASC  LAST_NAME_DESC
-------------- --------------
L1one          L4four        
L2two          L3three       
L3three        L2two         
L4four         L1one   

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM