我正在使用以下查询
SELECT d.mon,
CASE
WHEN MAX(CASE WHEN d.DRR = '80+' THEN 9999 ELSE TO_NUMBER(substr(d.DRR,1,INSTR(d.DRR, '-') - 1)) END) = 9999 THEN '80+'
WHEN MAX(CASE WHEN d.DRR = 'CURR' THEN 0 ELSE TO_NUMBER(substr(d.DRR,1,INSTR(d.DRR, '-') - 1)) END) = 0 THEN 'CURR'
ELSE(
TO_CHAR(max(TO_NUMBER(substr(d.DRR,1,INSTR(d.DRR, '-') - 1)))) || '-' ||
TO_CHAR(MAX( TO_NUMBER(substr(d.DRR,INSTR(d.DRR, '-') +1)) ))))
END
AS bill
FROM table d
GROUP BY d.mon
ORDER BY d.mon
但它给我的是无效的数字。我有以下数据集:
| Mon| DRR|
| --|--|
| 1 |80岁以上|
| 1 |1-30|
它应导致:
| Mon| DRR|
| --|--|
| 1 |80岁以上|
它不会工作,直到我添加以下条件:
TO_CHAR(MAX(CASE WHEN d.DRR = 'CURR' THEN 0 WHEN d.DRR = '80+' THEN 1 ELSE TO_NUMBER(substr(d.DRR,INSTR(d.DRR, '-') +1)) END))
为什么我需要添加这个条件,即使它满足了第一个条件。
2条答案
按热度按时间tgabmvqs1#
当然,你得到了 * 无效号码 * 错误。这是因为你试图将
to_number
函数应用于substr
的结果:这个查询应该做什么?情况看起来有点“复杂”。是否需要使用
max
功能?如果是,为什么?你在比较两个值,所以也许你只需要使用greatest
?你能用简单的英语解释一下你想解决的问题吗?哪些规则必须应用于 * 源 * 数据以获取 * 目标 * 数据?也许你的问题是(重要的是?))简化。7fhtutme2#
CASE
表达式使用短路逻辑,因此如果第一个WHEN
表达式匹配,则后续的WHEN
或ELSE
子句将不会被计算。但是,当您使用聚合函数时,解析整个结果集以评估第一个
WHEN
子句中的聚合,然后重新解析整个结果集以评估第二个WHEN
子句,等等CASE
表达式的每个子句,这是效率低下的;相反,SQL引擎将解析结果集一次并计算所有聚合的值,然后将使用聚合的结果应用CASE
表达式,这意味着将为所有聚合计算所有行。如果您尝试不使用聚合:
然后,查询成功完成,并应用短路逻辑,以便在
WHEN
子句中的任何一个匹配时都不计算ELSE
子句。但是,对于聚合,它不起作用。如果你想修复它,那么你需要防止不匹配
x-y
模式的字符串;您可以:使用正则表达式:
或者使用
INSTR
检查字符串中是否有连字符:或者过滤掉之前的匹配项:
其中,对于样本数据:
所有输出:
| Mon|法案|
| --|--|
| 1 |80岁以上|
fiddle