【发布时间】:2017-02-28 07:47:54
【问题描述】:
我正在尝试合并一些子查询,以避免多次访问大型表(42B 行)并获得
"[3771] CASE 表达式的 WHEN 子句中的非法表达式。"
,SUM(CASE
WHEN (oh.LOCN_NBR,oh.WK_NBR) IN (SELECT LOCN_NBR,START_WK FROM VT_STORES)
THEN oh.TTL_UN_QT
ELSE NULL
END) AS BEGINNING_OH
有什么方法可以在 CASE 语句中执行多列 IN 语句,还是我坚持将它们放在子查询中的连接/位置中?
编辑:根据要求进行完整查询:
SELECT
oh.LOCN_NBR AS LOCN_NBR
,item.ITEM_ID AS ITEM_ID
,SUM(CASE
WHEN oh.WK_NBR = (SELECT WK_NBR FROM ALEX_ARP_VIEWS_PRD.REF_CUSTOM_TIME WHERE cust_time_id=2 )
THEN oh.TTL_UN_QT
ELSE NULL
END) AS SALEABLE_QTY
,SUM(CASE
WHEN oh.WK_NBR = (SELECT LY_WK_NBR FROM ALEX_ARP_VIEWS_PRD.REF_CUSTOM_TIME WHERE cust_time_id=2 )
THEN oh.TTL_UN_QT
ELSE NULL
END) AS SALEABLE_QTY_LY
,SUM(CASE
WHEN (oh.LOCN_NBR,oh.WK_NBR) IN (SELECT LOCN_NBR,PRI_START_WK FROM VT_STORES)
THEN oh.TTL_UN_QT
ELSE NULL
END) AS BEGINNING_OH_LY
,SUM(CASE
WHEN (oh.LOCN_NBR,oh.WK_NBR) IN (SELECT LOCN_NBR,START_WK FROM VT_STORES)
THEN oh.TTL_UN_QT
ELSE NULL
END) AS BEGINNING_OH
FROM
ALEX_ARP_VIEWS_PRD.FACT_WKLY_OPR_INS oh
INNER JOIN VT_STORES stores ON oh.LOCN_NBR = stores.LOCN_NBR
INNER JOIN VT_ITEM item ON oh.VEND_PACK_ID = item.VEND_PACK_ID
WHERE
INS_TYP_CD='H'
AND TTL_UN_QT <> 0
AND WK_NBR >= (SELECT MIN(PRI_START_WK) FROM VT_STORES)
GROUP BY
oh.LOCN_NBR
,item.ITEM_ID
【问题讨论】:
-
VT_STORES的key是什么? -
locn_nbr 是 VT_STORES 的键
-
查询逻辑是否需要读取所有 42B 行,或者您会期望某些 where 条件显着限制数字?如果是这样,从计划中你看到这个限制有效吗?奇怪的是,大表是仅由我们看到的 5-6 个字段组成还是有很多额外的列?您需要在单个查询中完成所有逻辑,或者您可能会在临时/易失性表中使用一些步骤?
-
最大的问题是 INS_TYPE_CD 列没有被索引,鉴于它的大小和重要性,我无法说服 DBA 更改该表的结构 - 这消除了表中大约 50% 的数据马上。我对其他解决方案持开放态度,但我在温度/vt 方面所做的一切尝试都超过了我的线轴限制 (100G)。
-
在 50% 的情况下,我认为索引不会产生如此大的差异。也许分区会更有用。但是,如果你连数据都不能放在一个 vt/gtt 中,恐怕你真的需要增加你的 spool。