先谢谢,我使用的是oracle 10g。在SQL case语句中,我们传递值并根据值和返回字符串检查大小写。但我没有返回String,而是想返回一个表达式。这是否可以使用oracle SQL查询CASE语句返回表达式?我执行以下操作,oracle生成错误ORA-00905:Missing Keyword
SELECT ECL_CONTROL,
CASE
WHEN ECL_CONTROL = 'N' THEN ('##0') = ('##0')
WHEN ECL_CONTROL = 'Y' THEN (NVL(IL.ECL, 'X') = NVL(IM.ECL, 'X'))
END
FROM ITEM_CONTROL WHERE ITEM_NO = '2N2907A'
但以下成功运行:
SELECT ECL_CONTROL,
CASE
WHEN ECL_CONTROL = 'N' THEN 'test'
WHEN ECL_CONTROL = 'Y' THEN 'demo'
END
FROM ITEM_CONTROL WHERE ITEM_NO = '2N2907A'
我想将此查询用作内部查询以及外部查询的返回和表达式。我的查询如下:
SELECT LSM.ACTIVE_FLAG, LSM.ITEM_NO, IL.ECL, LSM.SERIAL_NO, IL.WAREHOUSE, IL.BIN, LSM.TOOL_STATUS_CODE,
LLG.NEXT_CAL_DATE, IM.PRODUCT_GROUP
FROM LS_SERIAL_MASTER LSM, LS_LIFE_LOG LLG, ITEM_LOCATION IL, ITEM_MASTER IM
WHERE IL.PLANT = IM.PLANT AND IL.ITEM_NO = IM.ITEM_NO
AND IM.PLANT = LSM.PLANT AND IM.ITEM_NO = LSM.ITEM_NO AND NVL(IM.PRODUCT_GROUP, 'X') = NVL('PUMP', 'X')
AND LSM.PLANT = LLG.PLANT AND LSM.ITEM_NO = LLG.ITEM_NO AND LSM.SERIAL_NO = LLG.SERIAL_NO
AND LSM.LIFE_TRANS_ID = LLG.TRANS_ID AND LLG.SERIAL_NO = IL.SERIAL_NO
AND (SELECT ECL_CONTROL,
CASE ECL_CONTROL
WHEN ECL_CONTROL = 'N' THEN ('##0' = '##0')
WHEN ECL_CONTROL = 'Y' THEN (NVL(IL.ECL, 'X') = NVL(IM.ECL, 'X'))
END AS ECL_CONTROL_TXT
FROM ITEM_CONTROL WHERE ITEM_NO = '2N2907A')
AND LLG.MAINT_LMT_ID IN('T', 'U')
AND LLG.NEXT_CAL_DATE BETWEEN TO_DATE('02/1/2014', 'MM/DD/YYYY') AND TO_DATE('02/11/2014', 'MM/DD/YYYY').
我的实际任务是从内部查询返回一个表达式并在外部查询中使用。
答案 0 :(得分:1)
不,你所展示的是不可能的。真正在select
中使用表达式是没有意义的。你可以have an expression evaluated instead of using a fixed string:
SELECT ECL_CONTROL,
CASE
WHEN ECL_CONTROL = 'N' THEN '##0'
WHEN ECL_CONTROL = 'Y' THEN NVL(IL.ECL, 'X')
END
FROM ITEM_CONTROL WHERE ITEM_NO = '2N2907A'
但你无法返回实际的表达方式。在您已经显示的代码中,第一个表达式总是会评估为true
(并且普通SQL中也不存在布尔值),所以我认为这可能是您实际想要的并且您对如何分配表达式值。您尚未显示IL
和IM
的来源,因此很难说出您想要的内容。
您可以直接在case
子句中使用where
:
SELECT ...
FROM IM, IL, ITEM_CONTROL -- joined in some way
WHERE CASE
WHEN ECL_CONTROL = 'N' THEN '##0'
WHEN ECL_CONTROL = 'Y' THEN NVL(IL.ECL, 'X')
END = CASE
WHEN ECL_CONTROL = 'N' THEN '##0'
WHEN ECL_CONTROL = 'Y' THEN NVL(IM.ECL, 'X')
END
虽然这可能更清楚:
WHERE ECL_CONTROL = 'N' OR NVL(IL.ECL, 'X') = NVL(IM.ECL, 'X')
您添加的较大查询:
SELECT LSM.ACTIVE_FLAG, LSM.ITEM_NO, IL.ECL, LSM.SERIAL_NO, IL.WAREHOUSE,
IL.BIN, LSM.TOOL_STATUS_CODE, LLG.NEXT_CAL_DATE, IM.PRODUCT_GROUP
FROM LS_SERIAL_MASTER LSM, LS_LIFE_LOG LLG, ITEM_LOCATION IL, ITEM_MASTER IM
WHERE IL.PLANT = IM.PLANT AND IL.ITEM_NO = IM.ITEM_NO
AND IM.PLANT = LSM.PLANT AND IM.ITEM_NO = LSM.ITEM_NO
AND NVL(IM.PRODUCT_GROUP, 'X') = NVL('PUMP', 'X')
AND LSM.PLANT = LLG.PLANT AND LSM.ITEM_NO = LLG.ITEM_NO
AND LSM.SERIAL_NO = LLG.SERIAL_NO
AND LSM.LIFE_TRANS_ID = LLG.TRANS_ID AND LLG.SERIAL_NO = IL.SERIAL_NO
AND LLG.MAINT_LMT_ID IN('T', 'U')
AND LLG.NEXT_CAL_DATE BETWEEN TO_DATE('02/1/2014', 'MM/DD/YYYY')
AND TO_DATE('02/11/2014', 'MM/DD/YYYY')
AND ((SELECT ECL_CONTROL FROM ITEM_CONTROL WHERE ITEM_NO = '2N2907A') = 'N'
OR NVL(IL.ECL, 'X') = NVL(IM.ECL, 'X'))
...虽然因为子查询正在寻找一行 - 具有固定的item_no
,它与您在其他表中引用的同名的其他列有关 - 您可以将该表包含在其中主要查询。
无论哪种方式。顺便提一下,明确连接会更清楚;而不是问题的范围,但接受你的评论,item_no
实际上是相关的,如:
SELECT LSM.ACTIVE_FLAG, LSM.ITEM_NO, IL.ECL, LSM.SERIAL_NO, IL.WAREHOUSE,
IL.BIN, LSM.TOOL_STATUS_CODE, LLG.NEXT_CAL_DATE, IM.PRODUCT_GROUP
FROM LS_LIFE_LOG LLG
JOIN LS_SERIAL_MASTER LSM ON LSM.PLANT = LLG.PLANT
AND LSM.ITEM_NO = LLG.ITEM_NO
AND LSM.SERIAL_NO = LLG.SERIAL_NO
AND LSM.LIFE_TRANS_ID = LLG.TRANS_ID
JOIN ITEM_CONTROL IC ON IC.ITEM_NO = LSM.ITEM_NO
JOIN ITEM_MASTER IM ON IM.PLANT = LSM.PLANT
AND IM.ITEM_NO = IC.ITEM_NO
JOIN ITEM_LOCATION IL ON IL.PLANT = IM.PLANT
AND IL.ITEM_NO = IM.ITEM_NO
AND IL.SERIAL_NO = LLG.SERIAL_NO
AND (IC.ECL_CONTROL = 'N' OR NVL(IL.ECL, 'X') = NVL(IM.ECL, 'X'))
WHERE LLG.MAINT_LMT_ID IN ('T', 'U')
AND LLG.NEXT_CAL_DATE BETWEEN TO_DATE('02/1/2014', 'MM/DD/YYYY')
AND TO_DATE('02/11/2014', 'MM/DD/YYYY')
AND NVL(IM.PRODUCT_GROUP, 'X') = NVL('PUMP', 'X')
NVL('PUMP', 'X')
没有意义 - NVL()
在固定值附近毫无意义。也许代替AND NVL(IM.PRODUCT_GROUP, 'X') = NVL('PUMP', 'X')
而不是AND (IM.PRODUCT_GROUP IS NULL OR IM.PRODUCT_GROUP = 'PUMP')
?