我认为我的剧本应该正在运行,但可能并不是那么有效'主要的问题是我猜它运行时间太长,因此当我在工作中运行时,整个会话在完成之前就会中止。
我基本上有2张桌子 表A - 包含一个人做的每笔交易
Person's_ID Transaction TransactionDate
---------------------------------------
123 A 01/01/2017
345 B 04/06/2015
678 C 13/07/2015
123 F 28/10/2016
表B - 包含人的ID和GraduationDate
我想要做的是检查一个人是否有效。 有效=如果此人在毕业日期前一个月完成了至少一笔交易
运行时间太长,因为想象一下,如果我有数百万人,每个人进行多次交易,这些交易在表A中逐行记录
SELECT
PERSON_ID
FROM
(SELECT PERSON_ID, TRANSACTIONDATE FROM TABLE_A) A
LEFT JOIN
(SELECT CIN, GRAD_DATE FROM TABLE_B) B
ON A.PERSON_ID = B.PERSON_ID
AND TRANSACTIONDATE <= GRAD_DATE
WHERE TRANSACTIONDATE BETWEEN GRAD_DATE - INTERVAL '30' DAY AND GRAD_DATE;
*表A和B是连接表的产品,因此它们是次要的。
答案 0 :(得分:0)
如果您只想要活跃客户,我会尝试exists
:
SELECT PERSON_ID
FROM TABLE_A A
WHERE EXISTS (SELECT 1
FROM TABLE_B B
WHERE A.PERSON_ID = B.PERSON_ID AND
A.TRANSACTIONDATE BETWEEN B.GRAD_DATE - INTERVAL '30' DAY AND GRAD_DATE
);
但是,性能可能与您的查询类似。如果表真的是表,我会建议索引。实际上,您可能需要了解视图(以便创建更好的索引)或者使用临时表。
答案 1 :(得分:0)
非等连接可能效率很低(无论它是编码为连接还是不存在),但逻辑可以重写为:
SELECT
PERSON_ID
FROM
( -- combine both Selects
SELECT 0 AS flag -- indicating source table
PERSON_ID, TRANSACTIONDATE AS dt
FROM TABLE_A
UNION ALL
SELECT 1 AS flag,
PERSON_ID, GRAD_DATE
FROM TABLE_B
) A
QUALIFY
flag = 1 -- only return a row from table B
AND Min(dt) -- if the previous row (from table A) is within 30 days
Over (PARTITION BY PERSON_ID
ORDER BY dt, flag
ROWS BETWEEN 1 Preceding AND 1 Preceding) >= dt - 30
这假定每人只有一个表A行,否则MIN
必须更改为:
AND MAX(CASE WHEN flag = 1 THEN dt END) -- if the previous row (from table A) is within 30 days
Over (PARTITION BY PERSON_ID
ORDER BY dt, flag
ROWS UNBOUNDED Preceding) >= dt - 30