То, что вы ищете здесь, это выполнить некоторое уплотнение данных, заполняя пробелы в ваших данных.
Начиная с вашей малонаселенной таблицы, используя многораздельное внешнее соединение с таблицей плотных измерений, вы можете достичьgoal:
With Date_Dim(dt) as (
select date '2015-05-01'
+ numtoyminterval(level-1,'month')
from dual
connect by level <= 14
)
select t1.eid
, dd.dt
, nvl(t1.flag, 'V') flag
from Date_Dim dd
left join YourData t1 partition by (t1.EID)
on t1.dt = dd.dt;
В вышеприведенном коде я определяю выражение общей таблицы Date_Dim (CTE) как измерение с плотной датой и оставляю внешнее соединение его с YourData, разделяя соединение столбцом EID.Одно это гарантирует, что для каждого значения eid будет по крайней мере одна строка для каждого значения DT в таблице Date_Dim.Последний бит должен гарантировать, что ваш столбец флага возвращает 'V' вместо NULL, что просто обрабатывается функцией NVL в проекции запросов.
Вот SQL Fiddle , показывающий его вдействие и выходные данные, сгенерированные вышеуказанным запросом в этой скрипке:
Результаты :
| EID | DT | FLAG |
|-----|----------------------|------|
| 123 | 2015-05-01T00:00:00Z | E |
| 123 | 2015-06-01T00:00:00Z | H |
| 123 | 2015-07-01T00:00:00Z | V |
| 123 | 2015-08-01T00:00:00Z | V |
| 123 | 2015-09-01T00:00:00Z | V |
| 123 | 2015-10-01T00:00:00Z | E |
| 123 | 2015-11-01T00:00:00Z | V |
| 123 | 2015-12-01T00:00:00Z | V |
| 123 | 2016-01-01T00:00:00Z | V |
| 123 | 2016-02-01T00:00:00Z | E |
| 123 | 2016-03-01T00:00:00Z | V |
| 123 | 2016-04-01T00:00:00Z | V |
| 123 | 2016-05-01T00:00:00Z | V |
| 123 | 2016-06-01T00:00:00Z | V |
Если вы хотите запрос, подходящий длявставив обратно в исходную таблицу только недостающие столбцы EID / Date, вы можете добавить t1.flag в предложение WHERE, равное нулю.
поочередно
Если выкак запрос больше похож на ваш оригинал, вы можете использовать перекрестный продукт для генерации всех строк и минус исходные данные:
With Date_Dim(dt) as (
select date '2015-05-01'
+ numtoyminterval(level-1,'month')
from dual
connect by level <= 14
)
select t1.eid, dd.dt, 'V'
from Date_Dim dd
cross join YourData t1
minus
select eid, dt, 'V' from YourData