トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

10-274 distinct後のorder by

SQLパズル

disSortTable
ColA  ColB  ColC
----  ----  ----
   A     A     C
   A     A     C
   A     A     D
   A     A     D
   A     B     E
   A     B     E
   B     A     F
   C     B     A
   C     B     A
   D     E     G

重複行を排除し、
ColA || ColB || ColC
を、ColCの昇順で出力する。

出力結果
Cols
-----
C,B,A
A,A,C
A,A,D
A,B,E
B,A,F
D,E,G

こちらを参考にさせていただきました(英語)


データ作成スクリプト

create table disSortTable(ColA,ColB,ColC) as
select 'A','A','C' from dual union all
select 'A','A','C' from dual union all
select 'A','A','D' from dual union all
select 'A','A','D' from dual union all
select 'A','B','E' from dual union all
select 'A','B','E' from dual union all
select 'B','A','F' from dual union all
select 'C','B','A' from dual union all
select 'C','B','A' from dual union all
select 'D','E','G' from dual;


SQL

--■■■distinctを使う方法■■■
select ColA || ',' || ColB || ',' || ColC as Cols
from (select distinct ColA,ColB,ColC from disSortTable)
order by ColC;

--■■■group byを使う方法■■■
select Cols
from (select ColC,ColA || ',' || ColB || ',' || ColC as Cols
        from disSortTable)
group by Cols
order by min(ColC);

--■■■Row_Number関数を使う方法■■■
select Cols
from (select ColA || ',' || ColB || ',' || ColC as Cols,
      Row_Number() over(partition by ColA || ',' || ColB || ',' || ColC order by 1) as rn,
      Row_Number() over(order by ColC) as sortKey
        from disSortTable)
where rn = 1
order by sortKey;


解説

この場合は、インラインビューで事前にdistinctすればいいですね。

An alternative to DISTINCT
Oracle ACE DirectorのEddie Awadさんが書かれているように、ソート条件の複雑さに応じて、
・distinct
・group by
・Row_Number関数
を使い分けるといいようですね。

4-16 重複排除とソート
10-240 和集合を作成してソート
10-289 An alternative to DISTINCT