嗨,我遇到了SQL案例的麻烦,问题是我试图用7个不同的列运行案例,这些列根据ID可以具有不同种类的数据(字符串,日期,数字)。
这意味着在某些ID下,一列中的行将是字符串,而在其他ID下,一列中的行将是数字。
我意识到这不是结构化数据库的常规用法,但是此特定表用于特定目的,过去该方法被认为是有用的。
该情况仅在该列确实具有数字时才选择“ then”。但是,当我运行它时,我得到一个无效的号码ORA-01722。因为其中之一行将包含字符串og日期。
我正确地意识到了这一点,因为oracle在执行之前先对sql进行了评估,并且没有顺序执行,因此即使实际上不必在给定ID下对列进行计算,也会在这些列上产生错误。
我试图执行的代码如下,'then'之前的硬编码1和2将根据ctrl_id(唯一ID)而变化,这将是我们只看一眼的安全代码和一个list_val列/行,一个数字
WITH sampledata1 AS
(SELECT '1' ctrl_id, '23' list_val1, 'Textfield' list_val2
FROM dual),
sampledata2 AS
(SELECT '2' ctrl_id, 'Textfield' list_val1, '45' list_val2
FROM dual),
sampledata3 AS
(SELECT *
FROM sampledata1
UNION
SELECT *
FROM sampledata2)
SELECT CASE
WHEN ctrl_id = 1 THEN
AVG(list_val1)
over(PARTITION BY qd.ctrl_id ORDER BY qd.ctrl_id ASC)
WHEN ctrl_id = 2 THEN
AVG(list_val2)
over(PARTITION BY qd.ctrl_id ORDER BY qd.ctrl_id ASC)
END AS avg_val
FROM sampledata3 qd
关于如何进行这项工作的任何建议。解决方法还是其他方法?
提前谢谢。
---------下面的解决方案
我使用了下面发布的一些建议和解决方案,并使此代码有效。我将尝试在系统中实现它。感谢您为大家节省的很多麻烦。
WITH sampledata1
AS (SELECT '1' ctrl_id, '23' list_val1, 'Textfield' list_val2 FROM DUAL),
sampledata2
AS (SELECT '2' ctrl_id, 'Textfield' list_val1, '45' list_val2 FROM DUAL),
sampledata3
AS (SELECT * FROM sampledata1
UNION
SELECT * FROM sampledata2)
select ctrl_id,
avg(CASE WHEN TRIM(TRANSLATE(list_val1, ' +-.0123456789', ' ')) is null
then list_val1 else null end) over(PARTITION BY qd.ctrl_id ORDER BY qd.ctrl_id ASC) list_val1,
avg(CASE WHEN TRIM(TRANSLATE(list_val2, ' +-.0123456789', ' ')) is null
then list_val2 else null end) over(PARTITION BY qd.ctrl_id ORDER BY qd.ctrl_id ASC) list_val2
from sampledata3 qd
答案 0 :(得分:1)
类似于eq(variables['task.A.status'], 'failure')
的{{3}}不适用于AVG
数据类型,使用此类功能时必须使用VARCHAR
或NUMBER
。>
我将查询修改为使用数字而不是字符串
INTEGER
输出为
WITH sampledata1
AS (SELECT '1' ctrl_id, '23' list_val1, '43' list_val2 FROM DUAL),
sampledata2
AS (SELECT '2' ctrl_id, '34' list_val1, '45' list_val2 FROM DUAL),
sampledata3
AS (SELECT * FROM sampledata1
UNION
SELECT * FROM sampledata2)
SELECT CASE
WHEN ctrl_id = 1
THEN
AVG (list_val1)
OVER (PARTITION BY qd.ctrl_id ORDER BY qd.ctrl_id ASC)
WHEN ctrl_id = 2
THEN
AVG (list_val2)
OVER (PARTITION BY qd.ctrl_id ORDER BY qd.ctrl_id ASC)
END
AS avg_val
FROM sampledata3 qd
编辑1
也许您可以执行以下操作来首先确定行返回NUMERIC或NON-NUMERIC。
根据您的要求进行更改。
AVG_VAL
----------
23
45
答案 1 :(得分:1)
您可以尝试使用
之类的非数字符号过滤掉值AVG(CASE WHEN TRIM(TRANSLATE(list_val1, ' +-.0123456789', ' ')) is null then list_val1 else null end) OVER (...)
NB!不幸的是,诸如“ + 12-.3”之类的字符串也将被识别为数字,在这种情况下,您将获得相同的ora-01722