私が書いたら
select ename, to_char(hiredate,'fmDay') as "Day" order by "Day";
次に、Dayに基づいて結果をソートします。金曜日から、月曜日、最後の水曜日に、文字で並べ替えます。
しかし、私はそれを曜日で並べ替えたいです。月曜日から日曜日まで。
文字列で並べ替えているため、順序どおりに表示されます(何も選択していないため、これは機能しません)。
数値形式で曜日を作成するために使用される format model で並べ替えることができますが、D
ですが、これは日曜日が1であるため、mod()
を使用することをお勧めしますこれを機能させるために。
つまり、テーブルを想定する
create table a ( b date );
insert into a
select sysdate - level
from dual
connect by level <= 7;
これはうまくいくでしょう:
select mod(to_char(b, 'D') + 5, 7) as dd, to_char(b, 'DAY')
from a
order by mod(to_char(b, 'D') + 5, 7)
これが SQL Fiddle です。
あなたの場合、クエリは次のようになります:
select ename, to_char(hiredate,'fmDay') as "Day"
from my_table
order by mod(to_char(hiredate, 'D') + 5, 7)
TO_CHAR
の他の形式をご覧ください。 「fmDay」の代わりに「D」を使用すると、1から7までの曜日が表示されます。その後、簡単に並べ替えることができます。
日付形式のリストは次のとおりです: http://docs.Oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm
同じ要件が発生しました-クエリ結果を曜日で並べ替えますが、日曜日からは開始しません。 Oracleで次のクエリを使用して月曜日に開始しました。 (それを変更して、任意の曜日で注文を開始します。たとえば、「MONDAY」を「TUESDAY」に変更します。)
SELECT ename, to_char(hiredate, 'fmDAY') AS "Day"
FROM emp
ORDER BY (next_day(hiredate, 'MONDAY') - hiredate) DESC
または:
SELECT ename, to_char(hiredate, 'fmDAY') AS "Day"
FROM emp
ORDER BY (hiredate - next_day(hiredate, 'MONDAY'))
to_char
のD
形式マスクは、曜日を値1〜7にマッピングします。
だが!
この出力は、クライアントのNLS_TERRITORYの設定によって異なります。米国は日曜日を1日目と見なしますが、世界の他のほとんどの国では月曜日を開始と見なしています。
alter session set nls_territory = AMERICA;
with dts as (
select date'2018-01-01' + level - 1 dt
from dual
connect by level <= 7
)
select to_char ( dt, 'Day' ) day_name,
to_char ( dt, 'd' ) day_number
from dts
order by day_number;
DAY_NAME DAY_NUMBER
Sunday 1
Monday 2
Tuesday 3
Wednesday 4
Thursday 5
Friday 6
Saturday 7
alter session set nls_territory = "UNITED KINGDOM";
with dts as (
select date'2018-01-01' + level - 1 dt
from dual
connect by level <= 7
)
select to_char ( dt, 'Day' ) day_name,
to_char ( dt, 'd' ) day_number
from dts
order by day_number;
DAY_NAME DAY_NUMBER
Monday 1
Tuesday 2
Wednesday 3
Thursday 4
Friday 5
Saturday 6
Sunday 7
悲しいことに、他の多くのNLSパラメーターとは異なり、to_char
の3番目のパラメーターとしてNLS_TERRITORYを渡すことはできません。
with dts as (
select date'2018-01-01' dt
from dual
)
select to_char ( dt, 'Day', 'NLS_DATE_LANGUAGE = SPANISH' ) day_name
from dts;
DAY_NAME
Lunes
with dts as (
select date'2018-01-01' dt
from dual
)
select to_char ( dt, 'Day', 'NLS_TERRITORY = AMERICA' ) day_name
from dts;
ORA-12702: invalid NLS parameter string used in SQL function
したがって、D
を使用してソートするソリューションはすべてバグです。
これを回避するには、日付から最新の月曜日を差し引きます(今日が月曜日の場合、最新の月曜日=今日)。これを行うには、IW
フォーマットマスクを使用します。 ISO週の開始を返します。常に月曜日です。
with dts as (
select date'2018-01-01' + level - 1 dt
from dual
connect by level <= 7
)
select to_char ( dt, 'Day' ) day_name,
( dt - trunc ( dt, 'iw' ) ) day_number
from dts
order by day_number;
DAY_NAME DAY_NUMBER
Monday 0
Tuesday 1
Wednesday 2
Thursday 3
Friday 4
Saturday 5
Sunday 6
日曜日と土曜日の並べ替えの場合、ISO週の開始を見つける前に日付に1を追加します。
with dts as (
select date'2018-01-01' + level - 1 dt
from dual
connect by level <= 7
)
select to_char ( dt, 'Day' ) day_name,
( dt - trunc ( dt + 1, 'iw' ) ) day_number
from dts
order by day_number;
DAY_NAME DAY_NUMBER
Sunday -1
Monday 0
Tuesday 1
Wednesday 2
Thursday 3
Friday 4
Saturday 5
SELECT
*
FROM
classes
ORDER BY
CASE
WHEN Day = 'Sunday' THEN 1
WHEN Day = 'Monday' THEN 2
WHEN Day = 'Tuesday' THEN 3
WHEN Day = 'Wednesday' THEN 4
WHEN Day = 'Thursday' THEN 5
WHEN Day = 'Friday' THEN 6
WHEN Day = 'Saturday' THEN 7
END ASC
ユーザーがクラスと呼ばれるテーブルを持っていると仮定します。そのテーブルのユーザーは、class_id(主キー)、クラス名、Dayを持っています。
月曜日を常に週の最初の日として扱う場合は、次のように使用できます。
-- Not affected by NLS_TERRITORY
-- ALTER SESSION SET NLS_TERRITORY="AMERICA"; -- Sunday is first day of week
-- ALTER SESSION SET NLS_TERRITORY="GERMANY"; -- Monday is first day of week
SELECT *
FROM tab
ORDER BY 1+TRUNC(dt)-TRUNC(dt,'IW');
日に対応する1〜7の番号を持つ別の列を追加して、この列で並べ替えることができるのに、なぜ複雑になるのか...
それは簡単です。
_SELECT last_name, hire_date,TO_CHAR(hire_date, 'DAY') DAY
FROM employees
ORDER BY TO_CHAR(hire_date - 1, 'd');
_
TO_CHAR(hire_date - 1, 'd')
は、「Monday」を「Sunday」という名前のボックスに入れます。
言われているように、そのための関数があります:
SELECT *
FROM table
ORDER BY WEEKDAY(table.date);
これはSQLでトリックを行うはずです:
ORDER BY
CASE DATENAME(dw,<<enter your date variable here>>)
WHEN 'Monday' THEN 1
WHEN 'Tuesday' THEN 2
WHEN 'Wednesday' THEN 3
WHEN 'Thursday' THEN 4
WHEN 'Friday' THEN 5
WHEN 'Saturday' THEN 6
WHEN 'Sunday' Then 7
END ASC;
もちろん、別の順序が必要な場合は、後で値を切り替えるだけです。
ベンの答えを改善して、0ではなく1から始まる結果を提供しました。クエリは次のようになります。
select
mod(to_char(b, 'D')+ 5, 7) +1 as dd,
to_char(b, 'DAY')
from a
order by mod(to_char(b, 'D')+ 5, 7);
一方、週を日曜日から開始する場合は、次のクエリを使用する必要があります。
select
mod(to_char(b, 'D')+ 6, 7) +1 as dd,
to_char(b, 'DAY')
from a
order by mod(to_char(b, 'D')+ 6, 7)
お役に立てれば :)
私はあなたがそれを好きであることを願っていくつかの簡単なアイデアを持っています。どのSQLを使用しているかわからないので、構文エラーを修正してください。
_select ename, to_char(hiredate,'fmDay') as "Day" from ABC_TABLE
JOIN (VALUES (1,'Monday'),(2,'Tuesday'),(3,'Wednesday'),(4,'Thursday'),(5,'Friday'),(6,'Saturday'),(7,'Sunday')) weekdays(seq,[Days]) on
ABC_TABLE.to_char(hiredate,'fmDay') = weekdays.[Days]
order by weekdays.seq;
_
私はあなたが次の週の終わりから次の週を始めたいと思っているなら、月の四分の一を見つけて、クロースで順番に追加します。
(MSSQL)のfind Quarterのちょうどのため:select DatePart(QUARTER, cast(cast(mydate as char(8)) as date))
with s as (select trunc(sysdate) + level dt from dual connect by level <= 7)
select to_char(dt, 'fmDay', 'nls_date_language=English') d
from s
order by dt - trunc(dt, 'iw');
D
------------------------------------
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
7 rows selected.