Oracle
 sql >> Base de données >  >> RDS >> Oracle

Créer une liste de tous les mois à partir d'une colonne de date dans ORACLE SQL

Vous avez fait une faute de frappe et avez écrit date au lieu de dates mais vous devez également faire un deuxième changement et utiliser ADD_MONTHS dans le WHERE de la requête récursive clause ou vous générerez un trop grand nombre de lignes.

WITH t1(test)  AS (
  SELECT MIN(alldates)
  FROM dates 
UNION ALL 
  SELECT ADD_MONTHS(test,1)
  FROM t1 
  WHERE ADD_MONTHS(test,1) <= (SELECT MAX(alldates) FROM dates)
)
SELECT * FROM t1

Qui sort :

Cependant, une requête plus efficace consisterait à obtenir les valeurs minimale et maximale dans la même requête, puis à itérer en utilisant ces limites prédéfinies :

WITH t1(min_date, max_date)  AS (
  SELECT MIN(alldates),
         MAX(alldates)  
  FROM   dates 
UNION ALL 
  SELECT ADD_MONTHS(min_date,1),
         max_date
  FROM   t1 
  WHERE  ADD_MONTHS(min_date,1) <= max_date
)
SELECT min_date AS month
FROM   t1

db<>violon ici

Mettre à jour

Oracle 11gR2 a des bogues gérant les requêtes de date récursives; ceci est corrigé dans les versions ultérieures d'Oracle, mais si vous souhaitez utiliser SQL Fiddle et Oracle 11gR2, vous devez itérer sur une valeur numérique et non sur une date. Quelque chose comme ça :

SQL Fiddle

Configuration du schéma Oracle 11g R2 :

CREATE TABLE dates(
alldates date);

INSERT INTO dates  (alldates) VALUES ('1-May-2017');
INSERT INTO dates  (alldates) VALUES ('1-Mar-2018');

Requête 1 :

WITH t1(min_date, month, total_months)  AS (
  SELECT MIN(alldates),
         0,
         MONTHS_BETWEEN(MAX(alldates),MIN(alldates))
  FROM   dates 
UNION ALL 
  SELECT min_date,
         month+1,
         total_months
  FROM   t1 
  WHERE  month+1<=total_months
)
SELECT ADD_MONTHS(min_date,month) AS month
FROM   t1

Résultats :

|                MONTH |
|----------------------|
| 2017-05-01T00:00:00Z |
| 2017-06-01T00:00:00Z |
| 2017-07-01T00:00:00Z |
| 2017-08-01T00:00:00Z |
| 2017-09-01T00:00:00Z |
| 2017-10-01T00:00:00Z |
| 2017-11-01T00:00:00Z |
| 2017-12-01T00:00:00Z |
| 2018-01-01T00:00:00Z |
| 2018-02-01T00:00:00Z |
| 2018-03-01T00:00:00Z |