web-dev-qa-db-fra.com

Trier par jour de la semaine du lundi au dimanche

Si j'écris

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

Ensuite, il trie le résultat en fonction de Day comme; vendredi, puis lundi et mercredi dernier, comme le tri par caractères.

Mais je veux le trier par jour de la semaine; du lundi au dimanche.

21
debaonline4u

Vous l'obtenez dans l'ordre où vous êtes parce que vous commandez par une chaîne (et cela ne fonctionnerait pas parce que vous ne sélectionnez rien).

Vous pouvez commander par le modèle de format utilisé pour créer le jour de la semaine sous forme numérique, D, mais comme dimanche est 1 dans ce que je recommanderais d'utiliser mod() pour que cela fonctionne.

c'est-à-dire en supposant que la table

create table a ( b date );

insert into a
 select sysdate - level
  from dual
connect by level <= 7;

Cela fonctionnerait:

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)

Voici un SQL Fiddle pour démontrer.

Dans votre cas, votre requête deviendrait:

select ename, to_char(hiredate,'fmDay') as "Day" 
  from my_table
 order by mod(to_char(hiredate, 'D') + 5, 7)
11
Ben

Jetez un œil à d'autres formats pour TO_CHAR. Au lieu de "fmDay", utilisez "D" et il vous donnera le jour de la semaine de 1 à 7. Ensuite, vous pourrez facilement le trier.

Voici une liste de formats de date: http://docs.Oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm

9
Andy Lester

Je viens de rencontrer la même exigence: commander un résultat de requête par jour de la semaine, mais pas à partir du dimanche. J'ai utilisé la requête suivante dans Oracle pour démarrer avec lundi. (Modifiez-le pour commencer la commande avec n'importe quel jour de la semaine, par exemple, changez 'LUNDI' en 'MARDI'.)

SELECT ename, to_char(hiredate, 'fmDAY') AS "Day" 
FROM emp
ORDER BY (next_day(hiredate, 'MONDAY') - hiredate) DESC

Ou:

SELECT ename, to_char(hiredate, 'fmDAY') AS "Day"
FROM emp
ORDER BY (hiredate - next_day(hiredate, 'MONDAY'))
8
2maraf

Le masque de format D de to_char associe les jours de la semaine aux valeurs 1 à 7.

Mais!

La sortie de ceci dépend du paramètre du client pour NLS_TERRITORY. Les États-Unis considèrent le dimanche comme le premier jour. Alors que la plupart des autres pays considèrent le lundi comme le début:

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

Malheureusement, contrairement à de nombreux autres paramètres NLS, vous ne pouvez pas passer NLS_TERRITORY comme troisième paramètre de to_char:

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

Donc, toute solution reposant sur D pour le tri est un bug!

Pour éviter cela, soustrayez le lundi le plus récent de la date (si aujourd'hui est lundi, le lundi le plus récent = aujourd'hui). Vous pouvez le faire avec le masque de format IW. Qui renvoie le début de la semaine ISO. C'est toujours un lundi:

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 

Pour le tri du dimanche au samedi, ajoutez un à la date avant de trouver le début de la semaine 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 + 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

En supposant que cet utilisateur possède une table appelée classes dans cet utilisateur de table a class_id (clé primaire), nom de classe, Day.

6
Ramya Roy

Si vous souhaitez que le lundi soit toujours traité comme le premier jour de la semaine, vous pouvez utiliser:

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

démo db <> violon

6
Lukasz Szozda

Pourquoi compliquer quand vous pouvez ajouter une autre colonne avec les numéros 1-7 correspondant aux jours puis trier par cette colonne ...

6
RealNmae

C'est simple.

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') place un 'lundi' dans une case nommée 'dimanche'.

5
bootsoon

Comme il est dit, il y a une fonction pour cela:

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

Cela devrait faire l'affaire en 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;

Bien sûr, si vous voulez un ordre différent, vous changez simplement les valeurs après cela.

1
Vladimir Filipovic

J'ai amélioré la réponse de Ben en vous donnant un résultat qui commence à 1 plutôt qu'à 0. La requête serait comme ceci:

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

D'un autre côté, si vous voulez que votre semaine commence à partir du dimanche, vous devez utiliser cette requête:

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)

J'espère que cela t'aides :)

1
Michele La Ferla

J'ai une idée simple j'espère que vous l'aimerez. Je ne sais pas quel SQL vous utilisez, veuillez corriger une erreur de syntaxe.

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;

Si vous voulez commencer la semaine prochaine après la fin d'une semaine, il vous suffit de trouver le quart de mois et de l'ajouter par ordre.

juste pour in de find Quarter in (MSSQL): 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