One way to differentiate between valte
values can be checking if string contains only digits or not (poor solution but should work):
WITH cte( vrec,valnum, valte) AS
(
SELECT 98945823 AS vrec, NULL AS valnum,'Total' AS valte FROM dual
UNION ALL SELECT 98945823, NULL, '06001' FROM dual
UNION ALL SELECT 98945823, 16.57, NULL FROM dual
UNION ALL SELECT 98945824, NULL, 'Total' FROM dual
UNION ALL SELECT 98945824, NULL, '06005' FROM dual
UNION ALL SELECT 98945824, 0.36, NULL FROM dual
)
SELECT
vrec
,MAX(CASE WHEN REGEXP_LIKE(valte, '^[[:digit:]]*$') THEN valte ELSE NULL END)
,MAX(CASE WHEN NOT REGEXP_LIKE(valte, '^[[:digit:]]*$') THEN valte ELSE NULL END)
,MAX(valnum)
FROM cte
GROUP BY vrec;
SqlFiddleDemo
Output:
╔═══════════╦═══════════════╦═══════════════╦═════════════╗
║ VREC ║ MAX(CASE...) ║ MAX(CASE...) ║ MAX(VALNUM) ║
╠═══════════╬═══════════════╬═══════════════╬═════════════╣
║ 98945823 ║ 06001 ║ Total ║ 16.57 ║
║ 98945824 ║ 06005 ║ Total ║ 0.36 ║
╚═══════════╩═══════════════╩═══════════════╩═════════════╝
For your case exchange cte hardcoded values with:
select vrec, valnum, valte from val_tb where
recd in (select recd from rectb where setd = 17)
AND (vid = 3 OR vid = 26 OR vid = 28);
Your data structure is very poor, so this solution is just workaround. You should really change underlying structure.