Case in Where 子句在 Teradata 上无法正常工作?
Case in Where clause not working properly on Teradata?
谁能告诉我我的查询有什么问题。我肯定知道 where 子句中的 case 语句肯定有问题。如果没有 Case 语句,此查询将 运行 正常。
错误 - SELECT 失败。 3707:Syntax 错误,应为“)”和“>=”之间的“END 关键字”
SELECT
mp.chnl_name AS mp_channel,
fsk.sku_prod_id AS pro_id,
fsk.dateint AS avlbl_dt,
fsk.sku_num AS sku,
fsk.upc_txt AS UPC,
Coalesce(fsk.brand_name,'N/A') AS brand,
fsk.ruckload AS LTL_Flag,
fsk.price_amt AS item_selling_price,
fsk.on_hand_unit_qty AS qoh,
fsk.netpropt AS profite,
(fsk.price_amt + fsk.shpg_amt) AS lms,
(GP)*100 AS net_pct
FROM EDW.ITEM_AVLBL mp
JOIN EDW.FULL_SKU fsk ON mp.item_id = fsk.item_id
JOIN EDW.SHORT_SKU ssk ON ssk.sh_sku_id = fsk.sh_sku_id
WHERE 1=1
AND mp.chnl_name LIKE '%google%' ---------- This is a prompt but I hard coded to test
AND fsk.item_create_dt >= '2019-10-20'
AND net_pct >= 10
AND CASE WHEN mp.chnl_name = 'CA_FACEBOOK' THEN ((GP)*100) >= 7 ELSE fsk.first_cost > 500 END
GROUP BY 1,2,3,4,5,6,7,8,9,10,11,fsk.first_cost
谁能告诉我如何解决这个问题?
不要使用 CASE
:
( (mp.chnl_name = 'CA_FACEBOOK' AND ((GP)*100) >= 7) OR
(mp.chnl_name <> 'CA_FACEBOOK' AND fsk.first_cost > 500)
)
问题是 Teradata 不支持从 CASE
表达式返回布尔类型。因此,您在 THEN
子句中的比较在句法上无法理解。
编辑:
根据您的评论,您想要的逻辑是:
( (mp.chnl_name = 'CA_FACEBOOK' AND ((GP)*100) >= 7 AND fsk.first_cost > 500
) OR
(mp.chnl_name <> 'CA_FACEBOOK' )
)
大小写在这里不起作用,您可以重写以使用 AND 和 OR
AND ( (mp.chnl_name = 'CA_FACEBOOK' AND ((GP)*100) >= 7 )
OR (mp.chnl_name != 'CA_FACEBOOK' AND fsk.first_cost > 500) )
根据你下面所说的,在where中添加以下内容:
AND ( (mp.chnl_name = 'CA_FACEBOOK' AND ((GP)*100) >= 7 AND fsk.first_cost > 500)
OR mp.chnl_name != 'CA_FACEBOOK'
)
这可能是您想要的:
WHERE
(mp.chnl_name <> 'CA_FACEBOOK'
AND mp.chnl_name LIKE '%google%' ---------- This is a prompt but I hard coded to test
AND fsk.item_create_dt >= '2019-10-20'
AND net_pct >= 10
OR (( mp.chnl_name = 'CA_FACEBOOK' AND GP*100 >= 7 AND fsk.first_cost > 500))
但是如果你在你的应用程序中创建这个 WHERE 条件(1=1
似乎表明了这一点)你最好在那里应用你的逻辑。
根据您的意见,原来的 ELSE 条件应该改为 ANDed:
SELECT
mp.chnl_name AS mp_channel,
fsk.sku_prod_id AS pro_id,
fsk.dateint AS avlbl_dt,
fsk.sku_num AS sku,
fsk.upc_txt AS UPC,
Coalesce(fsk.brand_name,'N/A') AS brand,
fsk.ruckload AS LTL_Flag,
fsk.price_amt AS item_selling_price,
fsk.on_hand_unit_qty AS qoh,
fsk.netpropt AS profite,
(fsk.price_amt + fsk.shpg_amt) AS lms,
(GP)*100 AS net_pct
FROM EDW.ITEM_AVLBL mp
JOIN EDW.FULL_SKU fsk ON mp.item_id = fsk.item_id
JOIN EDW.SHORT_SKU ssk ON ssk.sh_sku_id = fsk.sh_sku_id
WHERE 1=1
AND (mp.chnl_name LIKE '%google%' ---------- This is the prompt value
AND fsk.item_create_dt >= '2019-10-20'
AND net_pct >= 10
AND (mp.chnl_name <> 'CA_FACEBOOK' -- if not Facebook, don't care ORed terms
OR (GP*100 >= 7 AND fsk.first_cost > 500))
GROUP BY 1,2,3,4,5,6,7,8,9,10,11 /* ,fsk.first_cost */
我认为您不想按 first_cost 分组。这隐含地假设 mp.chnl_name 不为 NULL,因此它等于 CA_FACEBOOK 或不等于。如果允许 NULL,您还需要明确检查该条件,例如(mp.chnl_name <> 'CA_FACEBOOK' OR mp.chnl_name IS NULL)
.
这对我有用,但我可能在描述中混淆了你们。非常感谢您的快速回复。非常感谢您的帮助和时间。
AND (CASE WHEN mp.sls_trans_web_orgn_chnl_name = 'CA_FACEBOOK' AND fsk.full_sku_unit_first_cost < 500 AND (juice/NullIfZero(gms))*100 >= 7 THEN 1
WHEN mp.sls_trans_web_orgn_chnl_name <> 'CA_FACEBOOK' THEN 1 ELSE 0 END ) = 1
谁能告诉我我的查询有什么问题。我肯定知道 where 子句中的 case 语句肯定有问题。如果没有 Case 语句,此查询将 运行 正常。
错误 - SELECT 失败。 3707:Syntax 错误,应为“)”和“>=”之间的“END 关键字”
SELECT
mp.chnl_name AS mp_channel,
fsk.sku_prod_id AS pro_id,
fsk.dateint AS avlbl_dt,
fsk.sku_num AS sku,
fsk.upc_txt AS UPC,
Coalesce(fsk.brand_name,'N/A') AS brand,
fsk.ruckload AS LTL_Flag,
fsk.price_amt AS item_selling_price,
fsk.on_hand_unit_qty AS qoh,
fsk.netpropt AS profite,
(fsk.price_amt + fsk.shpg_amt) AS lms,
(GP)*100 AS net_pct
FROM EDW.ITEM_AVLBL mp
JOIN EDW.FULL_SKU fsk ON mp.item_id = fsk.item_id
JOIN EDW.SHORT_SKU ssk ON ssk.sh_sku_id = fsk.sh_sku_id
WHERE 1=1
AND mp.chnl_name LIKE '%google%' ---------- This is a prompt but I hard coded to test
AND fsk.item_create_dt >= '2019-10-20'
AND net_pct >= 10
AND CASE WHEN mp.chnl_name = 'CA_FACEBOOK' THEN ((GP)*100) >= 7 ELSE fsk.first_cost > 500 END
GROUP BY 1,2,3,4,5,6,7,8,9,10,11,fsk.first_cost
谁能告诉我如何解决这个问题?
不要使用 CASE
:
( (mp.chnl_name = 'CA_FACEBOOK' AND ((GP)*100) >= 7) OR
(mp.chnl_name <> 'CA_FACEBOOK' AND fsk.first_cost > 500)
)
问题是 Teradata 不支持从 CASE
表达式返回布尔类型。因此,您在 THEN
子句中的比较在句法上无法理解。
编辑:
根据您的评论,您想要的逻辑是:
( (mp.chnl_name = 'CA_FACEBOOK' AND ((GP)*100) >= 7 AND fsk.first_cost > 500
) OR
(mp.chnl_name <> 'CA_FACEBOOK' )
)
大小写在这里不起作用,您可以重写以使用 AND 和 OR
AND ( (mp.chnl_name = 'CA_FACEBOOK' AND ((GP)*100) >= 7 )
OR (mp.chnl_name != 'CA_FACEBOOK' AND fsk.first_cost > 500) )
根据你下面所说的,在where中添加以下内容:
AND ( (mp.chnl_name = 'CA_FACEBOOK' AND ((GP)*100) >= 7 AND fsk.first_cost > 500)
OR mp.chnl_name != 'CA_FACEBOOK'
)
这可能是您想要的:
WHERE
(mp.chnl_name <> 'CA_FACEBOOK'
AND mp.chnl_name LIKE '%google%' ---------- This is a prompt but I hard coded to test
AND fsk.item_create_dt >= '2019-10-20'
AND net_pct >= 10
OR (( mp.chnl_name = 'CA_FACEBOOK' AND GP*100 >= 7 AND fsk.first_cost > 500))
但是如果你在你的应用程序中创建这个 WHERE 条件(1=1
似乎表明了这一点)你最好在那里应用你的逻辑。
根据您的意见,原来的 ELSE 条件应该改为 ANDed:
SELECT
mp.chnl_name AS mp_channel,
fsk.sku_prod_id AS pro_id,
fsk.dateint AS avlbl_dt,
fsk.sku_num AS sku,
fsk.upc_txt AS UPC,
Coalesce(fsk.brand_name,'N/A') AS brand,
fsk.ruckload AS LTL_Flag,
fsk.price_amt AS item_selling_price,
fsk.on_hand_unit_qty AS qoh,
fsk.netpropt AS profite,
(fsk.price_amt + fsk.shpg_amt) AS lms,
(GP)*100 AS net_pct
FROM EDW.ITEM_AVLBL mp
JOIN EDW.FULL_SKU fsk ON mp.item_id = fsk.item_id
JOIN EDW.SHORT_SKU ssk ON ssk.sh_sku_id = fsk.sh_sku_id
WHERE 1=1
AND (mp.chnl_name LIKE '%google%' ---------- This is the prompt value
AND fsk.item_create_dt >= '2019-10-20'
AND net_pct >= 10
AND (mp.chnl_name <> 'CA_FACEBOOK' -- if not Facebook, don't care ORed terms
OR (GP*100 >= 7 AND fsk.first_cost > 500))
GROUP BY 1,2,3,4,5,6,7,8,9,10,11 /* ,fsk.first_cost */
我认为您不想按 first_cost 分组。这隐含地假设 mp.chnl_name 不为 NULL,因此它等于 CA_FACEBOOK 或不等于。如果允许 NULL,您还需要明确检查该条件,例如(mp.chnl_name <> 'CA_FACEBOOK' OR mp.chnl_name IS NULL)
.
这对我有用,但我可能在描述中混淆了你们。非常感谢您的快速回复。非常感谢您的帮助和时间。
AND (CASE WHEN mp.sls_trans_web_orgn_chnl_name = 'CA_FACEBOOK' AND fsk.full_sku_unit_first_cost < 500 AND (juice/NullIfZero(gms))*100 >= 7 THEN 1
WHEN mp.sls_trans_web_orgn_chnl_name <> 'CA_FACEBOOK' THEN 1 ELSE 0 END ) = 1