Oracle データベースのテーブルに対して特別なクエリを実行したいと考えています。
私が持っている列挙型に従って結果をソートしたい。
列挙型は次のようになります。
private enum days
{
Saturday = 1,
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
}
この列挙型に従って結果をソートしたい。
Oracle データベースのテーブルに対して特別なクエリを実行したいと考えています。
私が持っている列挙型に従って結果をソートしたい。
列挙型は次のようになります。
private enum days
{
Saturday = 1,
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
}
この列挙型に従って結果をソートしたい。
したがって、ENUM はデータベースが認識できないフロントエンドのものです。できることは、そのロジックをクエリに複製することだけです。Oracle では、CASE() などの関数を使用して、列の値をソート用の別の値に変換できます。
SQL> select d2
2 , to_char(d2, 'DY')
3 from t34
4 ORDER BY CASE to_char(d2, 'DY')
5 WHEN 'SAT' THEN 1
6 WHEN 'SUN' THEN 2
7 WHEN 'MON' THEN 3
8 WHEN 'TUE' THEN 4
9 WHEN 'WED' THEN 5
10 WHEN 'THU' THEN 6
11 WHEN 'FRI' THEN 7
12 ELSE 100 END
13 /
D2 TO_
--------- ---
25-JUL-10 SUN
24-AUG-10 TUE
13-JUL-10 TUE
26-MAY-10 WED
15-APR-10 THU
25-JUN-10 FRI
6 rows selected.
SQL>
日付の省略形の正確な値は、NLS_DATE_LANGUAGE パラメータの設定によって異なります。 詳細をご覧ください。
Oracle の日付フォーマットでは、DATE を曜日の数値に変換することもできます。これは文化的なものです。月曜日を週の最初の日とする社会もあれば、日曜日または土曜日とする社会もあります。したがって、TO_CHAR(some_date, 'D') は、ヨーロッパでは月曜日であるが米国では 2 である日付に対して 1 を返します。これは、NLS_TERRITORY 設定によって制御されます。 詳細をご覧ください。
TO_CHAR(date_col, 'D') が土曜日の日付に対して 1 を返すように Territory が設定されている場合、ORDER BY 句ははるかに単純になります。
SQL> select * from nls_session_parameters
2 where parameter = 'NLS_TERRITORY'
3 /
PARAMETER VALUE
------------------------------ -----------------
NLS_TERRITORY UNITED KINGDOM
SQL> select d2
2 , to_char(d2, 'DY')
3 , to_char(d2, 'D')
4 from t34
5 ORDER BY to_char(d2, 'D')
6 /
D2 TO_ T
--------- --- -
13-JUL-10 TUE 2
24-AUG-10 TUE 2
26-MAY-10 WED 3
15-APR-10 THU 4
25-JUN-10 FRI 5
25-JUL-10 SUN 7
6 rows selected.
SQL>
NLS_TERRITORY を変更すると、それに応じて結果セットの順序が変わります。
SQL> alter session set nls_territory='MOROCCO'
2 /
Session altered.
SQL> select d2
2 , to_char(d2, 'DY')
3 , to_char(d2, 'D')
4 from t34
5 ORDER BY to_char(d2, 'D')
6 /
D2 TO_ T
-------- --- -
25-07-10 SUN 2
24-08-10 TUE 4
13-07-10 TUE 4
26-05-10 WED 5
15-04-10 THU 6
25-06-10 FRI 7
6 rows selected.
SQL>
order by
case to_char(datecol, 'D')
when 1 then 2
when 2 then 3
...
when 7 then 1
end
私はAPCソリューションに賛成しました。これが最善/正しい方法です。
ただし、任意のデータセットによる順序付けの一般的なケースに適用される回答を追加したかったのです。
(この特定のケースでは、順序付けは任意ではありません。これは、単純な SQL 関数として記述できるものです。そうする必要があります)。
ここで重要なことは、列挙型が SET であることです。テーブルもセットであり、ビューも同様です。列挙型をテーブルまたはビューに変換するだけで、SQL クエリでこのテーブルに結合したり、並べ替えたりすることができます。
これは、多くのクエリで再利用する必要がある場合に特に便利です。
このような小さな固定セットの場合は、それをビューにハードコードするだけです。より大きなセットの場合は、インデックス付きテーブルの方が適しています。
正直に言うと、それが実際に1回限りの場合、順序付けが単一のクエリでのみ使用されることがわかっている場合は、主な回答でCASEアプローチを使用します。