我使用下面的代码来创建表,这应该最多需要30分钟。但有一段时间需要超过90分钟。请帮我修改一下
create table age_temp
as
SELECT co.circle, co.canumber, sum(age1) age1, sum(age2) age2, sum(age3) age3, sum(age4) age4,
sum(age5) age5, sum(age6) age6, sum(age7) age7, sum(age8) age8
FROM
(SELECT cta.szpartitionfield circle, cta.ifield1 CANUMBER,
CASE WHEN ohstatus IN ('CO','CM') THEN
ohopnamt_doc
ELSE CASE WHEN ohstatus IN ('IN','FC') THEN
CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) < 1 THEN
ohopnamt_doc
ELSE 0
END
ELSE 0
END
END age1,
CASE WHEN ohstatus IN ('IN','FC') THEN
CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 1 AND
MONTHS_BETWEEN(SYSDATE,ohrefdate) < 2 THEN
ohopnamt_doc
ELSE 0
END
END age2,
CASE WHEN ohstatus IN ('IN','FC') THEN
CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 2 AND
MONTHS_BETWEEN(SYSDATE,ohrefdate) < 3 THEN
ohopnamt_doc
ELSE 0
END
END age3,
CASE WHEN ohstatus IN ('IN','FC') THEN
CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 3 AND
MONTHS_BETWEEN(SYSDATE,ohrefdate) < 4 THEN
ohopnamt_doc
ELSE 0
END
END age4,
CASE WHEN ohstatus IN ('IN','FC') THEN
CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 4 AND
MONTHS_BETWEEN(SYSDATE,ohrefdate) < 5 THEN
ohopnamt_doc
ELSE 0
END
END age5,
CASE WHEN ohstatus IN ('IN','FC') THEN
CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 5 AND
MONTHS_BETWEEN(SYSDATE,ohrefdate) < 6 THEN
ohopnamt_doc
ELSE 0
END
END age6,
CASE WHEN ohstatus IN ('IN','FC') THEN
CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 6 AND
MONTHS_BETWEEN(SYSDATE,ohrefdate) < 7 THEN
ohopnamt_doc
ELSE 0
END
END age7,
CASE WHEN ohstatus IN ('IN','FC') THEN
CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 7 THEN
ohopnamt_doc
ELSE 0
END
ELSE 0
END age8
FROM
CDCDATA.ORDERHDR_ALL ORD, cash_temp ct, CDCDATA.customer_all cu, CMS_CDC.COL_TRN_AGREEMENT cta where ct.customer_id = ORD.customer_id
and ord.customer_id = cu.customer_id
and cu.custnum = cta.szlegacyagreementno ) co
GROUP BY co.circle, co.canumber;
答案 0 :(得分:0)
如果没有获取此查询中使用的基表(或其他表)的实际数据和表结构的详细信息,则很难修改查询。但下面可能会有所帮助:
在花费超过预期时间时,检查是否在创建此表的同时运行任何其他进程。可能是某些其他进程阻止了一个表,如果这些表或占用了所有资源。
检查并行性 - 不使用并行,看看需要多长时间并使用该参数。需要考虑并行级别的基表。
将此查询拆分为多个查询 - 您当前正在按案例,分组等处理数据。将每个操作拆分为单独的查询。
希望这会有所帮助。
答案 1 :(得分:0)
尝试使用一个支点(下面可能不完全正常,因为我没有样本数据,但应该让你走上正确的轨道):
WITH prep AS (
SELECT
cta.szpartitionfield circle
, cta.ifield1 canumber
, CASE
WHEN ohstatus IN('CO', 'CM') THEN 1
ELSE MAX(MIN(CEIL(MONTHS_BETWEEN(SYSDATE, ohrefdate)),8),1)
END piv_col
-- Round the 'months_between' up and cap it at 8
-- Then force CO and CM stats to be 1 since we want them added in there
-- Make sure no negatives or 0s get in... probably not needed
, CASE WHEN ohstatus IN('IN', 'FC') THEN ohopnamt_doc ELSE 0 END ohstat
-- Will only be non-zero for IN or FC status
FROM cdcdata.orderhdr_all ord
INNER JOIN cash_temp ct
ON ord.customer_id = ct.customer_id
INNER JOIN cdcdata.customer_all cu
ON ord.customer_id = cu.customer_id
INNER JOIN cms_cdc.col_trn_agreement cta
ON cu.custnum = cta.szlegacyagreementno
)
SELECT *
FROM prep PIVOT(
SUM(ohstat) -- Sum, split by values 1-8
FOR (piv_col) IN (
1 AS age1, 2 AS age2, 3 AS age3, 4 AS age4
, 5 AS age5, 6 AS age6, 7 AS age7, 8 AS age8
)
)
;
这应该产生一个如下所示的结果集:
CIRCLE CANUMBER AGE1 AGE2 AGE3 AGE4 AGE5 AGE6 AGE7 AGE8
------- --------- ----- ----- ----- ----- ----- ----- ----- -----
a 1 5 1 5 12 1 0 12 16
b 2 2 5 12 7 4 2 3 3
c 3 0 3 2 1 0 21 5 3
d 4 1 2 1 1 7 5 3 11
希望这有帮助!
如果没有,请为每个表发布DESCRIBE
输出,并从每个表中发布一些相互关联的样本数据(5行)。
此外,您为表格设置了别名,但ohstatus
ohrefdate
ohopnamt_doc
列没有别名,因此我必须在整个连接而不是特定表格上进行准备工作(我有点假设它们来自cdcdata.orderhdr_all
),这可能会节省一些处理时间。