Bonjour, dites-moi, s'il vous plaît, comment briser l'intervalle entre les dates ligne par ligne. J'ai une table:
SELECT trunc(t.start_dte) + level -1 dte FROM (select * from data
where data.end_dte != to_date('31.12.2999 23:59:59','dd.mm.yyyy hh24:mi:ss')) t
CONNECT BY level < trunc(t.end_dte) - trunc(t.start_dte) + 1
Je veux obtenir le résultat:
with result_data as (
SELECT 1 AS id, 232 AS status, to_date('21.08.2019') AS dte FROM dual
UNION ALL
SELECT 1 AS id, 232 AS status, to_date('22.08.2019') AS dte FROM dual
UNION ALL
SELECT 1 AS id, 232 AS status, to_date('23.08.2019') AS dte FROM dual
UNION ALL
SELECT 1 AS id, 232 AS status, to_date('24.08.2019') AS dte FROM dual
UNION ALL
SELECT 1 AS id, 235 AS status, to_date('25.08.2019') AS dte FROM dual
UNION ALL
SELECT 1 AS id, 235 AS status, to_date('26.08.2019') AS dte FROM dual
UNION ALL
SELECT 1 AS id, 233 AS status, to_date('27.08.2019') AS dte FROM dual
UNION ALL
SELECT 1 AS id, 233 AS status, to_date('28.08.2019') AS dte FROM dual
UNION ALL
SELECT 2 AS id, 301 AS status, to_date('20.08.2019') AS dte FROM dual
UNION ALL
SELECT 2 AS id, 301 AS status, to_date('21.08.2019') AS dte FROM dual
UNION ALL
SELECT 2 AS id, 301 AS status, to_date('22.08.2019') AS dte FROM dual
UNION ALL
SELECT 2 AS id, 264 AS status, to_date('23.08.2019') AS dte FROM dual
UNION ALL
SELECT 2 AS id, 264 AS status, to_date('24.08.2019') AS dte FROM dual
UNION ALL
SELECT 2 AS id, 264 AS status, to_date('25.08.2019') AS dte FROM dual
UNION ALL
SELECT 2 AS id, 259 AS status, to_date('26.08.2019') AS dte FROM dual
UNION ALL
SELECT 2 AS id, 259 AS status, to_date('27.08.2019') AS dte FROM dual
UNION ALL
SELECT 2 AS id, 259 AS status, to_date('28.08.2019') AS dte FROM dual)
select * from result_data
J'ai essayé de faire via cette requête, mais rien n'a fonctionné pour moi
with data as (
SELECT 1 AS id, 232 AS status, to_date('21.08.2019 10:47:39','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('25.08.2019 0:19:37','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 1 AS id, 235 AS status, to_date('25.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('27.08.2019 0:25:11','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 1 AS id, 233 AS status, to_date('27.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('31.12.2999 23:59:59','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 2 AS id, 301 AS status, to_date('20.08.2019 10:47:39','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('23.08.2019 0:19:37','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 2 AS id, 264 AS status, to_date('23.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('26.08.2019 0:25:11','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 2 AS id, 259 AS status, to_date('26.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('31.12.2999 23:59:59','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual)
select * from data
Il y a beaucoup de lignes dans le tableau, y a-t-il des réflexions sur la façon de procéder rationnellement?
3 Réponses :
Ok, je comprends maintenant. Le processus s'appelle la densification des données. Vous pouvez google pour cela.
with data as (
SELECT 1 AS id, 232 AS status, to_date('21.08.2019 10:47:39','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('25.08.2019 0:19:37','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 1 AS id, 235 AS status, to_date('25.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('27.08.2019 0:25:11','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 1 AS id, 233 AS status, to_date('27.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('31.12.2999 23:59:59','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 2 AS id, 301 AS status, to_date('20.08.2019 10:47:39','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('23.08.2019 0:19:37','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 2 AS id, 264 AS status, to_date('23.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('26.08.2019 0:25:11','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 2 AS id, 259 AS status, to_date('26.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('31.12.2999 23:59:59','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual)
,ref_dates as ( select (select min(trunc(start_dte)) from data) + level dd from dual
connect by (select min(trunc(start_dte)) from data) + level
<= (select max(trunc(end_dte)) from data where end_dte != to_date('31.12.2999 23:59:59','dd.mm.yyyy hh24:mi:ss')) )
select id,status,dd vol from data partition by (status)
left join ref_dates x on (dd >=trunc(start_dte) and dd <= trunc(end_dte) )
where 1=1
order by status,dd
Arkadiusz Łukasiewicz, l'utilisateur souhaite générer les lignes manquantes avec le montant maximum disponible jusqu'à cette date.
@AnkitBajpai Vous avez raison! Avec valeur de statut.
J'ai commenté les plages de dates qui se terminent en 2999 sur votre exemple pour que le résultat soit plus clair:
with
maxdays
as
(select max( end_dte-start_dte )+1 days from
(SELECT 1 AS id, 232 AS status, to_date('21.08.2019 10:47:39','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('25.08.2019 0:19:37','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 1 AS id, 235 AS status, to_date('25.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('27.08.2019 0:25:11','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
--UNION ALL
--SELECT 1 AS id, 233 AS status, to_date('27.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('31.12.2999 23:59:59','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 2 AS id, 301 AS status, to_date('20.08.2019 10:47:39','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('23.08.2019 0:19:37','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 2 AS id, 264 AS status, to_date('23.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('26.08.2019 0:25:11','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
--UNION ALL
--SELECT 2 AS id, 259 AS status, to_date('26.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('31.12.2999 23:59:59','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
)
),
data
as
(select level-1 l from maxdays connect by level <= days )
select id,status,start_dte+l
from data, (SELECT 1 AS id, 232 AS status, to_date('21.08.2019 10:47:39','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('25.08.2019 0:19:37','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 1 AS id, 235 AS status, to_date('25.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('27.08.2019 0:25:11','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
--UNION ALL
--SELECT 1 AS id, 233 AS status, to_date('27.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('31.12.2999 23:59:59','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 2 AS id, 301 AS status, to_date('20.08.2019 10:47:39','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('23.08.2019 0:19:37','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
UNION ALL
SELECT 2 AS id, 264 AS status, to_date('23.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('26.08.2019 0:25:11','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
--UNION ALL
--SELECT 2 AS id, 259 AS status, to_date('26.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('31.12.2999 23:59:59','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual
)
where l <= end_dte-start_dte
order by 2,3,1;
Excellent! C'est ce dont j'ai besoin! Merci beaucoup.
Je pense que la bonne réponse ne produit pas le résultat souhaité.
Vous pouvez essayer la requête suivante:
SQL> with data as (
2 SELECT 1 AS id, 232 AS status, to_date('21.08.2019 10:47:39','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('25.08.2019 0:19:37','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual UNION ALL
3 SELECT 1 AS id, 235 AS status, to_date('25.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('27.08.2019 0:25:11','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual UNION ALL
4 SELECT 1 AS id, 233 AS status, to_date('27.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('31.12.2999 23:59:59','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual UNION ALL
5 SELECT 2 AS id, 301 AS status, to_date('20.08.2019 10:47:39','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('23.08.2019 0:19:37','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual UNION ALL
6 SELECT 2 AS id, 264 AS status, to_date('23.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('26.08.2019 0:25:11','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual UNION ALL
7 SELECT 2 AS id, 259 AS status, to_date('26.08.2019 19:11:00','dd.mm.yyyy hh24:mi:ss') AS start_dte, to_date('31.12.2999 23:59:59','dd.mm.yyyy hh24:mi:ss') AS end_dte FROM dual)
8 ,D AS (select ID, STATUS, TRUNC(start_dte) AS start_dte, TRUNC(end_dte) AS end_dte from data)
9 SELECT
10 ID,
11 STATUS,
12 START_DTE
13 FROM
14 (
15 SELECT DISTINCT
16 ID,
17 STATUS,
18 START_DTE + LEVEL - 1 AS START_DTE,
19 END_DTE
20 FROM
21 D
22 CONNECT BY
23 LEVEL <= TRUNC(CASE
24 WHEN END_DTE = DATE '2999-12-31' THEN START_DTE + 1
25 ELSE END_DTE
26 END) - START_DTE + 1
27 )
28 WHERE
29 START_DTE != END_DTE
30 ORDER BY
31 ID,
32 START_DTE
33 ;
ID STATUS START_DTE
---------- ---------- ---------
1 232 21-AUG-19
1 232 22-AUG-19
1 232 23-AUG-19
1 232 24-AUG-19
1 235 25-AUG-19
1 235 26-AUG-19
1 233 27-AUG-19
1 233 28-AUG-19
2 301 20-AUG-19
2 301 21-AUG-19
2 301 22-AUG-19
ID STATUS START_DTE
---------- ---------- ---------
2 264 23-AUG-19
2 264 24-AUG-19
2 264 25-AUG-19
2 259 26-AUG-19
2 259 27-AUG-19
16 rows selected.
SQL>
Cheers !!
p >