Sim*_*ley 9 sql oracle recursion
这个问题的扩展和简化的版本这个问题.
我一直试图在SQL中解决以下迭代方程:
U^{F,D}_{t,p} = (\sum_{D} U^{F,D}_{t-1,p} + C_{t-1,p} )*R^{F,D}_{t-1,p}
这导致:
我能想到的最接近的类比是,U^{F,D}_{t,p}许多汽车经销商()都可以提供F某种颜色(D)的品牌汽车.所以上面的等式基本上说:从前一天(即)获取汽车的单位,总和颜色(),然后将前一天的值加上总和(不管是什么),并乘以其他一些号之前从天(,不管它是什么太).ptt-1U^{F,D}_{t-1,p}\sum_{D}CC_{t-1,p}RR^{F,D}_{t-1,p}
我设法解决了上述等式的简化形式,即:
即,没有汽车颜色的总和(D).示例数据和SQL查询都在我链接的小提琴中,但我将其粘贴在此处以供参考:
完整数据:
CREATE TABLE DYNAMICS ( T DATE, T_M1 DATE, P INTEGER, F VARCHAR(255), DELTA_F VARCHAR(255), R_T_M1 NUMBER, C_T_M1 NUMBER, U_T_M1 NUMBER, R_T NUMBER, C_T NUMBER, U_T NUMBER );
-- DAY 1, P_1
INSERT INTO DYNAMICS VALUES ( TO_DATE('01.01.2015','DD.MM.YYYY HH24:MI:SS'), TO_DATE('31.12.2014','DD.MM.YYYY HH24:MI:SS'), 1,'BMW','RED', 0.5, 0.6, NULL, 0.7,0.8,100.0 );
INSERT INTO DYNAMICS VALUES ( TO_DATE('01.01.2015','DD.MM.YYYY HH24:MI:SS'), TO_DATE('31.12.2014','DD.MM.YYYY HH24:MI:SS'), 1,'MERCEDES','RED', 0.5, 0.6, NULL, 0.7,0.8,50.0 );
-- DAY 1, P_2
INSERT INTO DYNAMICS VALUES ( TO_DATE('01.01.2015','DD.MM.YYYY HH24:MI:SS'), TO_DATE('31.12.2014','DD.MM.YYYY HH24:MI:SS'), 2,'BMW','RED', 0.5, 0.6, NULL, 0.7,0.8,10.0 );
INSERT INTO DYNAMICS VALUES ( TO_DATE('01.01.2015','DD.MM.YYYY HH24:MI:SS'), TO_DATE('31.12.2014','DD.MM.YYYY HH24:MI:SS'), 2,'MERCEDES','RED', 0.5, 0.6, NULL, 0.7,0.8,5.0 );
-- DAY 2, P_1
INSERT INTO DYNAMICS VALUES ( TO_DATE('02.01.2015','DD.MM.YYYY HH24:MI:SS'), TO_DATE('01.01.2015','DD.MM.YYYY HH24:MI:SS'), 1,'BMW','RED', 0.7, 0.8, 100, 0.9,0.9, NULL );
INSERT INTO DYNAMICS VALUES ( TO_DATE('02.01.2015','DD.MM.YYYY HH24:MI:SS'), TO_DATE('01.01.2015','DD.MM.YYYY HH24:MI:SS'), 1,'MERCEDES','RED', 0.7, 0.8, 50, 0.6,0.5, NULL );
-- DAY 2, P_2
INSERT INTO DYNAMICS VALUES ( TO_DATE('02.01.2015','DD.MM.YYYY HH24:MI:SS'), TO_DATE('01.01.2015','DD.MM.YYYY HH24:MI:SS'), 2,'BMW','RED', 0.7, 0.8, 10, 0.7,0.8, NULL );
INSERT INTO DYNAMICS VALUES ( TO_DATE('02.01.2015','DD.MM.YYYY HH24:MI:SS'), TO_DATE('01.01.2015','DD.MM.YYYY HH24:MI:SS'), 2,'MERCEDES','RED', 0.7, 0.8, 5, 0.3,0.3, NULL );
-- DAY 3, P_1
INSERT INTO DYNAMICS VALUES ( TO_DATE('03.01.2015','DD.MM.YYYY HH24:MI:SS'), TO_DATE('02.01.2015','DD.MM.YYYY HH24:MI:SS'), 1,'BMW','RED', 0.9, 0.9, NULL, 0.2,0.3, NULL );
INSERT INTO DYNAMICS VALUES ( TO_DATE('03.01.2015','DD.MM.YYYY HH24:MI:SS'), TO_DATE('02.01.2015','DD.MM.YYYY HH24:MI:SS'), 1,'MERCEDES','RED', 0.6, 0.5, NULL, 1.7,1.8, NULL );
-- DAY 3, P_2
INSERT INTO DYNAMICS VALUES ( TO_DATE('03.01.2015','DD.MM.YYYY HH24:MI:SS'), TO_DATE('02.01.2015','DD.MM.YYYY HH24:MI:SS'), 2,'BMW','RED', 0.7, 0.8, NULL, 0.2,0.3, NULL );
INSERT INTO DYNAMICS VALUES ( TO_DATE('03.01.2015','DD.MM.YYYY HH24:MI:SS'), TO_DATE('02.01.2015','DD.MM.YYYY HH24:MI:SS'), 2,'MERCEDES','RED', 0.3, 0.3, NULL, 0.8,0.9, NULL );
Run Code Online (Sandbox Code Playgroud)
样本数据:
下面演示了汽车经销商的示例数据p=1,汽车F=BMW颜色模型D=RED(D来自DELTASQL中的数学方程式).初始条件(t=0)在这里2015-01-01.对于所有日子t,给出了t(R_T, C_T)和t-1(R_T_M1, C_T_M1)的所有参数.了解它们,任务是计算所有日子的汽车单位t > t=0.
| T | T_M1 | P | F | DELTA_F | R_T_M1 | C_T_M1 | U_T_M1 | R_T | C_T | U_T |
|---------------------------|----------------------------|---|-----|---------|--------|--------|--------|-----|-----|--------|
| January, 01 2015 00:00:00 | December, 31 2014 00:00:00 | 1 | BMW | RED | 0.5 | 0.6 | (null) | 0.7 | 0.8 | 100 |
| January, 02 2015 00:00:00 | January, 01 2015 00:00:00 | 1 | BMW | RED | 0.7 | 0.8 | 100 | 0.9 | 0.9 | (null) |
| January, 03 2015 00:00:00 | January, 02 2015 00:00:00 | 1 | BMW | RED | 0.9 | 0.9 | (null) | 0.2 | 0.3 | (null) |
Run Code Online (Sandbox Code Playgroud)
查询:
为了解决简化问题,我在链接小提琴中提出了我在此处粘贴的查询以供参考:
--
-- SQL
-- T -> t
-- T_M1 -> t-1
--
WITH RECU( T, T_M1, P, F, DELTA_F,
R_T_M1, C_T_M1, U_T_M1,
R_T, C_T, U_T ) AS (
-- Anchor member.
SELECT T, T_M1, P, F, DELTA_F,
R_T_M1, C_T_M1,
U_T_M1,
R_T, C_T,
U_T
FROM DYNAMICS
-- Initial condition: U_{t-1} does not exist, and U_{t=0} is given
WHERE ( U_T_M1 IS NULL AND U_T IS NOT NULL )
UNION ALL
-- Recursive member.
SELECT NEW.T, NEW.T_M1, NEW.P, NEW.F, NEW.DELTA_F,
NEW.R_T_M1, NEW.C_T_M1,
RECU.U_T AS U_T_M1,
NEW.R_T, NEW.C_T,
-- Here the magic happens, i.e., (U_{t-1} + C_{t-1})*R_{t-1} = U_{t}
(RECU.U_T+NEW.C_T_M1)*NEW.R_T_M1 AS U_T
FROM DYNAMICS NEW
INNER JOIN RECU
ON
-- Translates: yesterday (t-1) of the new record equals today (t) of the parent record
NEW.T_M1 = RECU.T AND
NEW.P = RECU.P AND
NEW.F = RECU.F AND
NEW.DELTA_F = RECU.DELTA_F
)
SELECT * FROM RECU ORDER BY P, F, T;
Run Code Online (Sandbox Code Playgroud)
对于上面粘贴的示例数据,此查询会导致:
| T | T_M1 | P | F | DELTA_F | R_T_M1 | C_T_M1 | U_T_M1 | R_T | C_T | U_T |
|---------------------------|----------------------------|---|-----|---------|--------|--------|--------|-----|-----|--------|
| January, 01 2015 00:00:00 | December, 31 2014 00:00:00 | 1 | BMW | RED | 0.5 | 0.6 | (null) | 0.7 | 0.8 | 100 |
| January, 02 2015 00:00:00 | January, 01 2015 00:00:00 | 1 | BMW | RED | 0.7 | 0.8 | 100 | 0.9 | 0.9 | 70.56 |
| January, 03 2015 00:00:00 | January, 02 2015 00:00:00 | 1 | BMW | RED | 0.9 | 0.9 | 70.56 | 0.2 | 0.3 | 64.314 |
Run Code Online (Sandbox Code Playgroud)
哪个效果很好,即:2015-01-02 U_t = (100+0.8)*0.7 = 70.56,, 2015-01-03 , U_t = (70.56+0.9)*0.9 = 64.314.
查询的编写方式使其适用于不同的汽车经销商和不同的汽车品牌,可以检查在链接的小提琴中运行查询
上面的查询无法正确处理原始等式中汽车颜色的总和:
这与简化数据无关,因为所有汽车(BMW和MERCEDES)仅在RED中出现,因此颜色总和有效消失.
这样的完整逻辑应该可以通过GROUP BY/SUM内置于上述原始查询中的表达式来实现.不幸的是,我不知道该怎么做.
因此,想象一下你的形状数据就像简化问题部分一样,但现在每个汽车品牌都有两种颜色,例如,在这个链接的小提琴中:
| T | T_M1 | P | F | DELTA_F | R_T_M1 | C_T_M1 | U_T_M1 | R_T | C_T | U_T |
|---------------------------|----------------------------|---|----------|---------|--------|--------|--------|-----|-----|--------|
| January, 01 2015 00:00:00 | December, 31 2014 00:00:00 | 2 | MERCEDES | BLACK | 0.2 | 0.6 | (null) | 0.5 | 0.8 | 5.5 |
| January, 01 2015 00:00:00 | December, 31 2014 00:00:00 | 2 | MERCEDES | RED | 0.5 | 0.6 | (null) | 0.7 | 0.8 | 5 |
| January, 02 2015 00:00:00 | January, 01 2015 00:00:00 | 2 | MERCEDES | BLACK | 0.5 | 0.8 | 5.5 | 1.3 | 0.5 | (null) |
| January, 02 2015 00:00:00 | January, 01 2015 00:00:00 | 2 | MERCEDES | RED | 0.7 | 0.8 | 5 | 4.3 | 0.5 | (null) |
| January, 03 2015 00:00:00 | January, 02 2015 00:00:00 | 2 | MERCEDES | BLACK | 1.3 | 0.5 | (null) | 0.3 | 0.9 | (null) |
| January, 03 2015 00:00:00 | January, 02 2015 00:00:00 | 2 | MERCEDES | RED | 4.3 | 0.5 | (null) | 0.4 | 0.9 | (null) |
Run Code Online (Sandbox Code Playgroud)
根据这些数据,您可以预期经销商的p=2 F=MERCEDES汽车动态如下:
U^{MERCEDES,BLACK}_{T=2015-01-02,P=2} = ( (5.5 + 5) + 0.8 )*0.5 = 11.3*0.5 = 5.65
U^{MERCEDES,RED}_{T=2015-01-02,P=2} = ( (5.5 + 5) + 0.8 )*0.7 = 11.3*0.7 = 7.91
U^{MERCEDES,BLACK}_{T=2015-01-03,P=2} = ( (5.65 + 7.91) + 0.5 )*1.3 = 14.06*1.3 = 18.278
U^{MERCEDES,RED}_{T=2015-01-03,P=2} = ( (5.65 + 7.91) + 0.5 )*4.3 = 14.06*4.3 = 60.458
Run Code Online (Sandbox Code Playgroud)
问题是如何调整上面的简化查询来解决这个问题.
我不认为这是最好的答案,但我认为它为您提供了您正在寻找的结果。
WITH RECU( T, T_M1, P, F, DELTA_F,
R_T_M1, C_T_M1, U_T_M1,
R_T, C_T, U_T ) AS (
-- Anchor member.
SELECT T, T_M1, P, F, DELTA_F,
R_T_M1, C_T_M1,
U_T_M1,
R_T, C_T,
-- Start SUM of u_t
(select sum(u_t) from DYNAMICS d2
where d2.T=d1.T and d2.T_M1=d1.T_M1 and d2.P=d1.P and d2.F=d1.F
group by T, T_M1, P, F) as u_t
-- End SUM of u_t
FROM DYNAMICS d1
-- Initial condition: U_{t-1} does not exist, and U_{t=0} is given
WHERE ( U_T_M1 IS NULL AND U_T IS NOT NULL )
UNION ALL
-- Recursive member.
SELECT NEW.T, NEW.T_M1, NEW.P, NEW.F, NEW.DELTA_F,
NEW.R_T_M1, NEW.C_T_M1,
RECU.U_T AS U_T_M1,
NEW.R_T, NEW.C_T
,
-- Here the magic happens, i.e., (U_{t-1} + C_{t-1})*R_{t-1} = U_{t}
(
RECU.U_T
+NEW.C_T_M1)*NEW.R_T_M1 AS U_T
FROM DYNAMICS NEW
INNER JOIN RECU
ON
-- Translates: yesterday (t-1) of the new record equals today (t) of the parent record
NEW.T_M1 = RECU.T AND
NEW.P = RECU.P AND
NEW.F = RECU.F AND
NEW.DELTA_F = RECU.DELTA_F
)
SELECT * FROM RECU ORDER BY P, F, T;
Run Code Online (Sandbox Code Playgroud)
我添加的内容是在Start SUM of u_t和End SUM of u_t评论之间,这是小提琴。