我试图合并一些子查询以避免多次敲击一个大表(42B行)并获得
" [3771] CASE表达式的WHEN子句中的非法表达。"
Integer[] intValues = new Integer [] {1,2,3,4,5};
Integer[] outputValues = Arrays.stream(intValues).map(i -> (i*2)).toArray(Integer[] :: new);
Arrays.stream(outputValues).forEach(x -> System.out.println(x));
有没有办法在CASE语句中执行多列IN语句,或者我是不是将它们放在子查询中的join / where中,因为它是当前的?
编辑:按要求进行完整查询:
,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
答案 0 :(得分:0)
您不需要使用IN
。您可以使用exists
:
SUM(CASE WHEN EXISTS (SELECT 1 FROM VT_STORES v WHERE oh.LOCN_NBR = v.LOCN_NBR AND oh.WK_NBR = v.START_WK)
THEN oh.TTL_UN_QT
END) AS BEGINNING_OH
但是,我并非100%确定问题是IN
。许多数据库不允许子查询作为聚合函数的参数。我不确定Teradata是否允许此功能。
答案 1 :(得分:0)
我正在尝试整合一些子查询以避免多次访问大量表
多列子查询仅在WHERE
中允许,但在CASE
中不允许。重写EXISTS
可能不会提高性能,计划可能实际上更复杂。
您只是尝试隐藏复杂性,但它仍然是后台的外部加入,如下所示:
,Sum(CASE WHEN stores.LOCN_NBR IS NOT NULL THEN oh.TTL_UN_QT END) AS BEGINNING_OH
...
FROM oh LEFT JOIN
(
SELECT LOCN_NBR,START_WK FROM VT_STORES
) AS stores
ON stores.LOCN_NBR = oh.LOCN_NBR
AND stores.START_WK = oh.WK_NBR
您能否显示当前查询(至少是您尝试优化的那些部分)?
修改强>
当VT_STORES.locn_nbr是唯一的时,这应该返回相同的结果:
SELECT
oh.LOCN_NBR AS LOCN_NBR
,item.ITEM_ID AS ITEM_ID
,Sum(CASE
WHEN oh.WK_NBR = (SELECT Min(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 Min(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.WK_NBR= stores.PRI_START_WK
THEN oh.TTL_UN_QT
END) AS BEGINNING_OH_LY
,Sum(CASE
WHEN oh.WK_NBR = stores.START_WK
THEN oh.TTL_UN_QT
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
其他Scalar子查询应该没问题,因为它们只返回一行而优化器知道这一点。
答案 2 :(得分:0)
re:有没有办法在CASE语句中做多列IN语句
没有
re:避免多次击中一张大表(42B行)
哪一个很大?我不知道,即使复合IN
子句有效,与使用where
子句的连接/添加列相比,您也可以避免多次访问大型表。
SELECT
...
,SUM(CASE
WHEN SELECT COUNT(*) FROM VT_STORES
WHERE LOCN_NBR = oh.LOCN_NBR AND
PRI_START_WK = oh.WK_NBR > 1
THEN oh.TTL_UN_QT
END) AS BEGINNING_OH_LY
,SUM(CASE
WHEN SELECT COUNT(*) FROM VT_STORES
WHERE LOCN_NBR = oh.LOCN_NBR AND
START_WK = oh.WK_NBR > 1
THEN oh.TTL_UN_QT
END) AS BEGINNING_OH
FROM
...
如果它VT_STORES
大,请尝试:
ALEX_ARP_VIEWS_PRD.FACT_WKLY_OPR_INS oh INNER JOIN
(select
LOCN_NBR,
PRI_START_WK,
START_WK
from
VT_STORES) stores ON
oh.LOCN_NBR = stores.LOCN_NBR and
(PRI_START_WK = oh.WK_NBR OR
START_WK = oh.WK_NBR)
虽然我已经看到在联接中使用OR
子句的性能命中率,但是你可能会更好地使用两个内连接,每周一个你想要的。