我需要过滤出表中numer_lini列中有数字的行,它在100到999之间,当我注释掉我将marsnr转换为整数的行时,下面的代码工作得很好。但是,当我尝试使用它时,我得到错误:在函数" INTEGER"的字符串参数中找到无效字符。当查看列表时看起来像替换和翻译过滤器只有数字就好并且选择仅包含合法数字(唯一值列表不长,因此易于通过眼睛扫描)。那么为什么它没有投出一些东西呢?我也尝试使用整数(marsnr),但它会产生相同的错误。我需要施法,因为我需要数值范围,否则我得到像7,80等结果。正如我所提到的,我正在使用IBM DB2数据库。
select numer_lini, war_trasy, id_prz1, id_prz2
from alaska.trasa
where numer_lini in (
select marsnr
from (
select
distinct numer_lini marsnr
from alaska.trasa
where case
when replace(translate(numer_lini, '0','123456789','0'),'0','') = ''
then numer_lini
else 'no'
end <> 'no'
)
where cast(marsnr as integer) between 100 and 999
)
fetch first 300 rows only
答案 0 :(得分:1)
如果您从Db2解释中查看优化的SQL,您将看到Db2已将您的代码折叠为单个选择。
SELECT DISTINCT Q2.NUMER_LINI AS "NUMER_LINI",
Q2.WAR_TRASY AS "WAR_TRASY",
Q2.ID_PRZ1 AS "ID_PRZ1",
Q2.ID_PRZ2 AS "ID_PRZ2",
Q1.NUMER_LINI
FROM ALASKA.TRASA AS Q1,
ALASKA.TRASA AS Q2
WHERE (Q2.NUMER_LINI = Q1.NUMER_LINI)
AND (100 <= INTEGER(Q1.NUMER_LINI))
AND (INTEGER(Q1.NUMER_LINI) <= 999)
AND (CASE WHEN (REPLACE(TRANSLATE(Q1.NUMER_LINI,
'0',
'123456789',
'0'),
'0',
'') = '') THEN Q1.NUMER_LINI
ELSE 'no' END <> 'no')
使用CASE强制Db2执行&#34;是整数&#34;先检查一下。另外,你不要检查空字符串。
E.g。使用此表和数据
create TABLE alaska.trasa (numer_lini VARCHAR(10), war_trasy INT , id_prz1 INT, id_prz2 INT);
insert into alaska.trasa values ('',1,1,1),('99',1,1,1),('500',1,1,1),('3000',1,1,1),('00300',1,1,1),('AXS',1,1,1);
此SQL工作
select numer_lini, war_trasy, id_prz1, id_prz2
from alaska.trasa
where case when translate(numer_lini, '','0123456789') = ''
and numer_lini <> ''
then integer(numer_lini) else 0 end
between 100 and 999
如果输入中存在嵌入空间,则会失败。例如。 '30 0'
。为了满足这一要求,可能首选常规表达。 E.g。
select numer_lini, war_trasy, id_prz1, id_prz2
from alaska.trasa
where case when regexp_like(numer_lini, '^\s*[+-]?\s*((\d+\.?\d*)|(\d*\.?\d+))\s*$'))
then integer(numer_lini) else 0 end
between 100 and 999