1

In Oracle, I have a table with a column (X) which can have strings like this:

97M
481
101X
88
21E
etc.

I want to select just those rows where the integral value of x > 90. In this example, I would expect to get back the rows containing values 97M, 101X and 481. How can I do this?

2
  • are these supposed to be hex strings? if so: TO_NUMBER(x, 'XXXXXXXX') > 90 Commented Jun 20, 2012 at 21:27
  • Sorry. This was perhaps a bad example. the numbers are not stored in hex. I will edit my original post. Commented Jun 20, 2012 at 21:31

3 Answers 3

6

I used REGEXP_REPLACE to remove the alpha characters before using TO_NUMBER so I could filter the results as needed:

WITH t
  AS (SELECT '97F' AS x FROM DUAL
      UNION
      SELECT '481' FROM dual
      UNION
      SELECT '101A' FROM dual
      UNION
      SELECT '101A' FROM dual
      UNION
      SELECT '88' FROM dual
      UNION
      SELECT '21E' FROM dual)
SELECT x
  FROM t
 WHERE TO_NUMBER(regexp_replace(x, '[[:alpha:]]', '')) > 90;

X
101A
481
97F

Hope it helps...

Sign up to request clarification or add additional context in comments.

7 Comments

I like this best, but I wonder about a string like: '88a1', and whether this should really pass or not.
sufficient for OP, but if somebody wanted to test the first number of 45A2, i suggest to_number(regexp_substr(x, '^\d*'))
@deathApril, I agree with you. But, horses for courses, the data the OP gave seemed fairly straightforward with no instances of letters between numbers. I didn't want to overcomplicate it.
@Ollie can you please provide a reason why do you find regexp_substr more complicated than regexp_replace?
@deathApril, that's an interesting perspective. Given the test data value of 45A98 would your code return it or not? How would you know if the OP wanted the comparison made against the "45" (fail) or the "98" (pass)? All I'm saying is that the answer meets the requirements of the question. If you see that as an opportunity for overcharging then we are on different wavelengths and will have to agree to differ.
|
3

You can always use translate to remove alpha characters.

TO_NUMBER(translate('90F', '1ABCDEFGHIJKLMNOPQRSTUFWXYZ', '1')) -- = 90

Translate does a 1 to 1 translation of the characters in the second argument to the characters in the third argument.

Here's a different example.

translate('ABCDEFG', 'ABC', 'XYZ') = 'XYZDEFG'

A -> X
B -> Y
C -> Z

Now if you look at my example

translate('90F', '1ABCDEFGHIJKLMNOPQRSTUFWXYZ', '1')

1 -> 1 (this is here because if that last argument is null, you'll get an empty string)
A -> ? there's nothing here, so oracle will translate it to nothing
B -> same as above

2 Comments

I like this, but I'm a little confused: shouldn't the translate translate '90F' into 901, replacing the F with a '1'?
@user1059096 Nope. I will edit my post to explain translate a bit more.
0

You might try the following:

WHERE (substr(x, 1, 1) = '9' and substr(x, 2, 1) between '1' and '9'
      ) or
      (substr(x, 1, 1) between '1' and '9' and
       substr(x, 2, 1) between '0' and '9' and
       substr(x, 3, 1) between '0' and '9'
      )

This is a bit brute force. It checks to see if the string starts with 91-99 or if the first three digits are a string.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.