select * from (select * from A29 WHERE 1 = 1 AND EXISTS
(SELECT 1 FROM A02 x WHERE x.a0000 = A29.A0000
AND x.a0201b LIKE '001.001.003%' and EXISTS (select 1 from a01 a01 where a01.A0000 = x.A0000 and a01.A0163 = '1') )
) A29
where 1=1 and (A29.A2949 is not null and A29.A2947 is not null and (CASE
When Nvl(Length(A29.A2949), 0) = 8 Then
To_Date(A29.A2949, 'yyyyMMdd')
When Nvl(Length(A29.A2949), 0) = 6 Then
To_Date(A29.A2949, 'yyyyMM')
When Nvl(Length(A29.A2949), 0) = 4 Then
To_Date(concat(A29.A2949, '01'), 'yyyyMM')
Else
Null
END) < (CASE
When Nvl(Length(A29.A2947), 0) = 8 Then
To_Date(A29.A2947, 'yyyyMMdd')
When Nvl(Length(A29.A2947), 0) = 6 Then
To_Date(A29.A2947, 'yyyyMM')
When Nvl(Length(A29.A2947), 0) = 4 Then
To_Date(concat(A29.A2947, '01'), 'yyyyMM')
Else
Null
END))
原本的sql就是上面这条,,A29表中一共有两条记录,其中一条记录的A2949字段格式是正确的,另外一条是错误的, 根据标红的这段sql执行后会查出格式正确的那一条记录,再以查询的这一条记录作为查询表时,还是报了无效的月份,where条件里的 To_Date函数还是走了A29的全部A2949字段 ,求助改怎么写才能过滤掉错误字段 ,使正确的那一条记录两个字段进行比较
(SELECT 1 FROM A02 x WHERE x.a0000 = A29.A0000
AND x.a0201b LIKE '001.001.003%' and EXISTS (select 1 from a01 a01 where a01.A0000 = x.A0000 and a01.A0163 = '1') )
) A29
where 1=1 and (A29.A2949 is not null and A29.A2947 is not null and (CASE
When Nvl(Length(A29.A2949), 0) = 8 Then
To_Date(A29.A2949, 'yyyyMMdd')
When Nvl(Length(A29.A2949), 0) = 6 Then
To_Date(A29.A2949, 'yyyyMM')
When Nvl(Length(A29.A2949), 0) = 4 Then
To_Date(concat(A29.A2949, '01'), 'yyyyMM')
Else
Null
END) < (CASE
When Nvl(Length(A29.A2947), 0) = 8 Then
To_Date(A29.A2947, 'yyyyMMdd')
When Nvl(Length(A29.A2947), 0) = 6 Then
To_Date(A29.A2947, 'yyyyMM')
When Nvl(Length(A29.A2947), 0) = 4 Then
To_Date(concat(A29.A2947, '01'), 'yyyyMM')
Else
Null
END))
原本的sql就是上面这条,,A29表中一共有两条记录,其中一条记录的A2949字段格式是正确的,另外一条是错误的, 根据标红的这段sql执行后会查出格式正确的那一条记录,再以查询的这一条记录作为查询表时,还是报了无效的月份,where条件里的 To_Date函数还是走了A29的全部A2949字段 ,求助改怎么写才能过滤掉错误字段 ,使正确的那一条记录两个字段进行比较
CASE
When Nvl(Length(A29.A2947), 0) = 8 Then
To_Date(A29.A2947, 'yyyyMMdd')
When Nvl(Length(A29.A2947), 0) = 6 Then
To_Date(A29.A2947, 'yyyyMM')
When Nvl(Length(A29.A2947), 0) = 4 Then
To_Date(concat(A29.A2947, '01'), 'yyyyMM')
Else
Null
END
只需一个函数即可替代:rpad(A29.A2947,8,'0101')
使用rpad函数执行sql还是会报无效的月份,问题在于如何避开错误格式的数据,如果避开了估计用哪个都是可以走的通的(不过我这个确实啰嗦了一点)
to_date(case when substr(rpad(A29.A2947,8,'0101'),5,2) between '01' and '12' then rpad(A29.A2947,8,'0101')
else substr(rpad(A29.A2947,8,'0101'),1,4)||'0101' end,'yyyymmdd')
您这段sql判断了如果格式是正确的直接转换日期对比,如果格式不正确就转换成正确格式再进行对比,无论数据正确与否都起到了转换的作用.而现在我要做的是 : 本来的A29的两条数据,根据过滤后取到一条数据,如果这条数据能直接转换的话直接转换,不能直接转换的还是需要抛错的,而不是直接转换掉,然后现在过滤后这一条数据是可以直接转换的,但是过滤前的那条数据是错误不能转换的,但是不在本次sql需要执行的对比范围之内,但sql还是做了转换并抛了无效的月份
重命名的A29和表名A29会不会有影响
用红色的这段sql单独执行查出来过了,是正确格式的.
重命名的A29我改成另外的别名也是一样会报错,所以我就又改回来了.