使用递归查询汇总期间

时间:2018-08-16 14:32:41

标签: teradata recursive-query teradata-sql-assistant

我需要使用“超前缓冲区”合并每个组(ID)的顺序事件(带有标识符NUM)的顺序事件的重叠时间段(由FROM和TO变量定义),这意味着如果下一个时间段在缓冲区内开始,它们应该合并。

例如;在下面的示例中,第二个事件(NUM = 2)在时间13开始,该时间在缓冲区(10 + 5 = 15)内。

与我发现的其他类似问题相比,这里的棘手部分是,尽管每个事件的缓冲期都有固定值,但是如果将其与具有更长缓冲期的事件(仅向后)合并,则可能会改变期间。

例如;事件3也合并到与事件1和2相同的时间段,因为这些事件的缓冲时间更长。接下来的缓冲区应该改为(25 + 5 = 30),而不是(25 + 3 = 28),这意味着以下事件4也应包含在这些时间段中。

再次将事件4的缓冲时间更改为5。但是,由于40> 31 + 5,最后一个事件是单独的观察。

customer_id COUNT(sessions)_1h  COUNT(transactions)_1h  COUNT(sessions)_1d COUNT(transactions)_1d
1           1                   17                      3                 43
2           3                   36                      3                 36
3           0                   0                       1                 25
4           0                   0                       0                 0
5           1                   15                      2                 29

最终,我需要的结果是两个“分离”时期的两个观察结果;

CREATE TABLE MY_TABLE(ID INTEGER, NUM INTEGER, FROM INTEGER, TO INTEGER, LOOKAHEAD INTEGER);
INSERT INTO MY_TABLE VALUES (1, 1, 1,  10, 5);
INSERT INTO MY_TABLE VALUES (1, 2, 13, 20, 5);
INSERT INTO MY_TABLE VALUES (1, 3, 21, 25, 3);
INSERT INTO MY_TABLE VALUES (1, 4, 29, 31, 3);
INSERT INTO MY_TABLE VALUES (1, 5, 40, 50, 3);

自然,我最初以为我可以通过创建一个新变量LOOKAHEAD2来创建此“ LOOKHEAD”变量,该变量是LOOKAHEAD2的先前值和LOOKAHEAD的当前值的最大值,条件是FROM(此记录)<(TO + LOOKAHEAD )(以前的记录)使用OLAP函数。但这实际上并不起作用,因为它是对自身的引用。

相反,我尝试使用递归查询,从第一个事件(ID = 1, FROM = 1, TO = 31) (ID = 5, FROM = 40, TO = 50) 开始,然后将表与下一个事件(NUM = 1)的条件(root.NUM+1 = next.NUM)递归地加入到表中,并进行更新相应地使用LOOKAHEAD变量。

但是我以前从未使用过递归查询,也无法将其加入到LOOKAHEAD值的更新值中。

有人知道如何通过递归查询或其他方式解决此问题吗?

1 个答案:

答案 0 :(得分:0)

您应该在分析函数中使用var car = new Array("Honda", "Toyota", "BMW", "Merc"); var calc = 3 * car.length; alert(calc);窗口修饰符(在Teradata 16中为RESET WHEN,在较早版本中为LAG);不要使用递归查询。

更新:

MAX
DROP TABLE MY_TABLE;
CREATE VOLATILE TABLE MY_TABLE 
( id          INTEGER
, num         INTEGER
, from_value  INTEGER
, to_value    INTEGER
, lookahead   INTEGER
) ON COMMIT PRESERVE ROWS;

INSERT INTO MY_TABLE VALUES (1, 1, 1,  10, 5);
INSERT INTO MY_TABLE VALUES (1, 2, 13, 20, 5);
INSERT INTO MY_TABLE VALUES (1, 3, 21, 25, 3);
INSERT INTO MY_TABLE VALUES (1, 4, 29, 31, 3);
INSERT INTO MY_TABLE VALUES (1, 5, 40, 50, 3);

INSERT INTO MY_TABLE VALUES (2, 1, 1, 10, 5);
INSERT INTO MY_TABLE VALUES (2, 2, 20, 30, 15);
INSERT INTO MY_TABLE VALUES (2, 3, 40, 41, 5);
INSERT INTO MY_TABLE VALUES (2, 4, 100, 200, 5);
INSERT INTO MY_TABLE VALUES (2, 5, 300, 400, 3);


SELECT  id, first_from_value, to_value
FROM  ( SELECT  id
              , to_value
              , CASE WHEN overlaps_flag = 1
                  THEN  NULL
                  ELSE  COALESCE 
                        ( MIN (from_value) 
                            OVER (PARTITION BY id
                                  ORDER BY from_value
                                  RESET WHEN MAX (overlaps_flag) 
                                               OVER (PARTITION BY id 
                                                     ROWS BETWEEN 
                                                          1 PRECEDING 
                                                      AND 1 PRECEDING) = 0
                                  ROWS BETWEEN UNBOUNDED PRECEDING 
                                           AND 1 PRECEDING)
                        , from_value )
                END AS first_from_value
        FROM  ( SELECT  id, from_value, to_value
                      , MAX (from_value) 
                          OVER (PARTITION BY id 
                                ORDER BY from_value 
                                ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
                          AS next_from_value
                      , CASE WHEN to_value + lookahead + 1 >= next_from_value
                          THEN 1 ELSE 0 
                        END AS overlaps_flag
                FROM  my_table
              ) AS a
      ) AS a
WHERE first_from_value IS NOT NULL
ORDER BY 1, 2