我有一些数据,其中数据中存在一个间隙,我需要这些间隙的值为“0”。鉴于以下数据,
thing
“a”、“b”和“c”理想情况下在给定时间段内具有 +/- 12 小时的数据。如果不存在数据,则应该是 0
select *
from (
select 'a' as thing, timestamp '2024-12-19 11:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 12:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 13:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 14:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 15:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 16:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 17:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 18:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 19:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 20:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 21:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 22:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 23:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'b' as thing, timestamp '2024-12-19 15:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'b' as thing, timestamp '2024-12-19 16:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'b' as thing, timestamp '2024-12-19 17:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'b' as thing, timestamp '2024-12-19 18:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'b' as thing, timestamp '2024-12-19 19:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'b' as thing, timestamp '2024-12-19 20:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'c' as thing, timestamp '2024-12-19 12:00:00' as t, DBMS_RANDOM.value() as v from dual
) where t between timestamp '2024-12-19 20:00:00' - interval '12' hour
and timestamp '2024-12-19 11:00:00' + interval '12' hour
我知道这是可能的,但我不太确定如何实现。
这可以通过生成您感兴趣的事物和时间的所有组合,然后将生成的数据进行左外连接到您的实际表来解决。
在您的示例中,它看起来像:
WITH input_data AS
(
select *
from (
select 'a' as thing, timestamp '2024-12-19 11:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 12:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 13:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 14:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 15:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 16:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 17:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 18:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 19:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 20:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 21:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 22:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'a' as thing, timestamp '2024-12-19 23:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'b' as thing, timestamp '2024-12-19 15:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'b' as thing, timestamp '2024-12-19 16:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'b' as thing, timestamp '2024-12-19 17:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'b' as thing, timestamp '2024-12-19 18:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'b' as thing, timestamp '2024-12-19 19:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'b' as thing, timestamp '2024-12-19 20:00:00' as t, DBMS_RANDOM.value() as v from dual union all
select 'c' as thing, timestamp '2024-12-19 12:00:00' as t, DBMS_RANDOM.value() as v from dual
)
)
,hours AS
(
select timestamp '2024-12-19 11:00:00' + numtodsinterval(rownum,'HOUR') as hr
from dual
connect by level <= 12
)
,things AS
(
SELECT DISTINCT thing FROM input_data
)
/*cross join to generate all the data you are wanting*/
, hourthings AS
(
SELECT hr, thing
FROM hours
CROSS JOIN things
)
/*now join it all together*/
SELECT
hourthings.thing,
hourthings.hr,
COALESCE(input_data.v, 0) as v
FROM hourthings
LEFT OUTER JOIN input_data
ON hourthings.thing = input_data.thing
AND hourthings.hr = input_data.t
ORDER BY thing, hr, v;
+-------+------------------------------+-----------------------------------------+
| THING | HR | V |
+-------+------------------------------+-----------------------------------------+
| a | 19-DEC-24 12.00.00.000000000 | .69774073052016968823672302782349609322 |
| a | 19-DEC-24 13.00.00.000000000 | .74681895242556208805921962750792112372 |
| a | 19-DEC-24 14.00.00.000000000 | .13895201336452094187697669624078005226 |
| a | 19-DEC-24 15.00.00.000000000 | .45337500667932949332016060056416492918 |
| a | 19-DEC-24 16.00.00.000000000 | .18899747383037346346775198378542334477 |
| a | 19-DEC-24 17.00.00.000000000 | .67102219547677447329531648462053776372 |
| a | 19-DEC-24 18.00.00.000000000 | .66857093410415223366767066184514813993 |
| a | 19-DEC-24 19.00.00.000000000 | .40391951442247044543080670749491385357 |
| a | 19-DEC-24 20.00.00.000000000 | .66678394623467745293923962502423558974 |
| a | 19-DEC-24 21.00.00.000000000 | .08192799627659883827769961887128183705 |
| a | 19-DEC-24 22.00.00.000000000 | .82864536740652777939535875967936388967 |
| a | 19-DEC-24 23.00.00.000000000 | .06074762180454381335128190562038752096 |
| b | 19-DEC-24 12.00.00.000000000 | 0 |
| b | 19-DEC-24 13.00.00.000000000 | 0 |
| b | 19-DEC-24 14.00.00.000000000 | 0 |
| b | 19-DEC-24 15.00.00.000000000 | .49068229240906850444551902753208786223 |
| b | 19-DEC-24 16.00.00.000000000 | .49309406570981735526120776844366484152 |
| b | 19-DEC-24 17.00.00.000000000 | .81504764682984037766335094773881648938 |
| b | 19-DEC-24 18.00.00.000000000 | .56003821415269263216558677201167824597 |
| b | 19-DEC-24 19.00.00.000000000 | .47232889342064636947176597827340419611 |
| b | 19-DEC-24 20.00.00.000000000 | .26243408497186222403849841769849597216 |
| b | 19-DEC-24 21.00.00.000000000 | 0 |
| b | 19-DEC-24 22.00.00.000000000 | 0 |
| b | 19-DEC-24 23.00.00.000000000 | 0 |
| c | 19-DEC-24 12.00.00.000000000 | .82675839474283690631176461696378570193 |
| c | 19-DEC-24 13.00.00.000000000 | 0 |
| c | 19-DEC-24 14.00.00.000000000 | 0 |
| c | 19-DEC-24 15.00.00.000000000 | 0 |
| c | 19-DEC-24 16.00.00.000000000 | 0 |
| c | 19-DEC-24 17.00.00.000000000 | 0 |
| c | 19-DEC-24 18.00.00.000000000 | 0 |
| c | 19-DEC-24 19.00.00.000000000 | 0 |
| c | 19-DEC-24 20.00.00.000000000 | 0 |
| c | 19-DEC-24 21.00.00.000000000 | 0 |
| c | 19-DEC-24 22.00.00.000000000 | 0 |
| c | 19-DEC-24 23.00.00.000000000 | 0 |
+-------+------------------------------+-----------------------------------------+
SQL 比必要的更详细,因为最后三个 CTE 可以折叠成单个语句,但这种更详细的编写将有助于理解每个逻辑步骤。