web-dev-qa-db-ja.com

月曜日から日曜日までの曜日で並べ替え

私が書いたら

select ename, to_char(hiredate,'fmDay') as "Day" order by "Day";

次に、Dayに基づいて結果をソートします。金曜日から、月曜日、最後の水曜日に、文字で並べ替えます。

しかし、私はそれを曜日で並べ替えたいです。月曜日から日曜日まで。

21
debaonline4u

文字列で並べ替えているため、順序どおりに表示されます(何も選択していないため、これは機能しません)。

数値形式で曜日を作成するために使用される 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)
11
Ben

TO_CHARの他の形式をご覧ください。 「fmDay」の代わりに「D」を使用すると、1から7までの曜日が表示されます。その後、簡単に並べ替えることができます。

日付形式のリストは次のとおりです: http://docs.Oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm

9
Andy Lester

同じ要件が発生しました-クエリ結果を曜日で並べ替えますが、日曜日からは開始しません。 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'))
8
2maraf

to_charD形式マスクは、曜日を値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 
7
Chris Saxon
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を持っています。

6
Ramya Roy

月曜日を常に週の最初の日として扱う場合は、次のように使用できます。

-- 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');

db <> fiddle demo

6
Lukasz Szozda

日に対応する1〜7の番号を持つ別の列を追加して、この列で並べ替えることができるのに、なぜ複雑になるのか...

6
RealNmae

それは簡単です。

_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」という名前のボックスに入れます。

5
bootsoon

言われているように、そのための関数があります

SELECT *
FROM table
ORDER BY WEEKDAY(table.date);
4
user3132457

これは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;

もちろん、別の順序が必要な場合は、後で値を切り替えるだけです。

1

ベンの答えを改善して、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)

お役に立てれば :)

1

私はあなたがそれを好きであることを願っていくつかの簡単なアイデアを持っています。どの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))

1
M Danish
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. 
1
akk0rd87