'A row for every month between status updates and untill the end of a period
In the dataset I have a row for every status change per student. They usually go from null > Registered > Intake > Registered or Rejected. The period start at January first and ends at July first.
Table 1
| Student_ID | Begin_date | End_date | From_Status | To_status |
|---|---|---|---|---|
| 1 | 20-1-2020 | 25-1-2020 | null | Registered |
| 1 | 25-1-2020 | 20-2-2020 | Registered | Intake |
| 1 | 20-2-2020 | 20-2-2020 | Intake | Admitted |
| 2 | 20-2-2020 | 25-2-2020 | null | Registered |
| 2 | 25-2-2020 | 4-4-2020 | Registered | Intake |
| 2 | 4-4-2020 | 4-4-2020 | Intake | Rejected |
I want to have a dataset in which I have a row for every month until the first of july. Furthermore, for every month in between status changes.
Desired results:
| Date_ID | Student_ID | Begin_date | End_date | From_Status | To_status |
|---|---|---|---|---|---|
| 20200101 | 1 | 20-1-2020 | 25-1-2020 | null | Registered |
| 20200102 | 1 | 25-1-2020 | 20-2-2020 | Registered | Intake |
| 20200102 | 1 | 20-2-2020 | 20-2-2020 | Intake | Admitted |
| 20200103 | 1 | 20-2-2020 | 20-2-2020 | Intake | Admitted |
| 20200104 | 1 | 20-2-2020 | 20-2-2020 | Intake | Admitted |
| 20200105 | 1 | 20-2-2020 | 20-2-2020 | Intake | Admitted |
| 20200106 | 1 | 20-2-2020 | 20-2-2020 | Intake | Admitted |
| 20200102 | 2 | 20-2-2020 | 25-2-2020 | null | Registered |
| 20200103 | 2 | 25-2-2020 | 4-4-2020 | Registered | Intake |
| 20200104 | 2 | 25-2-2020 | 4-4-2020 | Registered | Intake |
| 20200104 | 2 | 4-4-2020 | 4-4-2020 | Intake | Rejected |
| 20200105 | 2 | 4-4-2020 | 4-4-2020 | Intake | Rejected |
| 20200106 | 2 | 4-4-2020 | 4-4-2020 | Intake | Rejected |
In my database I am only allowed to create views, so I cannot add a date table.
Any suggestion? Thanks in advance!
Solution 1:[1]
Hopefully this could help:
WITH
grid AS
(
SELECT DISTINCT
To_Char(t.BEGIN_DATE, 'yyyy') || '01' || LPAD(LEVEL, 2, '0') "DATE_ID",
t.STUDENT_ID "STUDENT_ID",
CASE WHEN To_Char(t.BEGIN_DATE, 'yyyymm') = To_Char(t.BEGIN_DATE, 'yyyy') || LPAD(LEVEL, 2, '0') THEN t.BEGIN_DATE END "BEGIN_DATE",
CASE WHEN To_Char(t.BEGIN_DATE, 'yyyymm') = To_Char(t.BEGIN_DATE, 'yyyy') || LPAD(LEVEL, 2, '0') THEN t.END_DATE END "END_DATE",
CASE WHEN To_Char(t.BEGIN_DATE, 'yyyymm') = To_Char(t.BEGIN_DATE, 'yyyy') || LPAD(LEVEL, 2, '0') THEN t.FROM_STATUS END "FROM_STATUS",
CASE WHEN To_Char(t.BEGIN_DATE, 'yyyymm') = To_Char(t.BEGIN_DATE, 'yyyy') || LPAD(LEVEL, 2, '0') THEN t.TO_STATUS END "TO_STATUS"
FROM
TABLE1 t
CONNECT BY
LEVEL < 7
),
last_stats AS
(
SELECT
DATE_ID,
STUDENT_ID,
BEGIN_DATE,
END_DATE,
FROM_STATUS,
TO_STATUS,
X_BEGIN_DATE,
X_END_DATE
FROM
(
SELECT
To_Char(t.BEGIN_DATE, 'yyyy') || '01' || To_Char(t.BEGIN_DATE, 'mm') "DATE_ID",
STUDENT_ID "STUDENT_ID",
BEGIN_DATE "BEGIN_DATE",
END_DATE "END_DATE",
FROM_STATUS,
TO_STATUS,
Max(BEGIN_DATE) OVER(PARTITION BY STUDENT_ID ORDER BY STUDENT_ID, To_Char(t.BEGIN_DATE, 'yyyy') || '01' || To_Char(t.BEGIN_DATE, 'mm') RANGE UNBOUNDED PRECEDING) "X_BEGIN_DATE",
Max(END_DATE) OVER(PARTITION BY STUDENT_ID ORDER BY STUDENT_ID, To_Char(t.END_DATE, 'yyyy') || '01' || To_Char(t.END_DATE, 'mm') RANGE UNBOUNDED PRECEDING) "X_END_DATE"
FROM
TABLE1 t
)
ORDER BY
STUDENT_ID,
DATE_ID,
BEGIN_DATE
)
SELECT DISTINCT
t.DATE_ID "DATE_ID",
t.STUDENT_ID "STUDENT_ID",
t.X_BEGIN_DATE "BEGIN_DATE",
t.X_END_DATE "END_DATE",
Nvl(t.FROM_STATUS, ls.FROM_STATUS) "FROM_STATUS",
Nvl(t.TO_STATUS, ls.TO_STATUS) "TO_STATUS"
FROM
(
SELECT
DATE_ID,
STUDENT_ID,
BEGIN_DATE,
CASE WHEN BEGIN_DATE Is Null THEN Max(BEGIN_DATE) OVER(PARTITION BY STUDENT_ID ORDER BY STUDENT_ID, DATE_ID RANGE UNBOUNDED PRECEDING) ELSE BEGIN_DATE END "X_BEGIN_DATE",
CASE WHEN END_DATE Is Null THEN Max(END_DATE) OVER(PARTITION BY STUDENT_ID ORDER BY STUDENT_ID, DATE_ID RANGE UNBOUNDED PRECEDING) ELSE END_DATE END "X_END_DATE",
END_DATE,
FROM_STATUS,
TO_STATUS
FROM
grid
ORDER BY
STUDENT_ID,
DATE_ID
) t
LEFT JOIN
last_stats ls ON(ls.STUDENT_ID = t.STUDENT_ID And ls.BEGIN_DATE = t.X_BEGIN_DATE And ls.END_DATE = t.X_END_DATE)
WHERE
t.X_BEGIN_DATE Is Not Null And t.X_END_DATE Is Not Null
ORDER BY
STUDENT_ID, DATE_ID
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
