SQL Query - Greater Than with Text Data Type - sql

I've searched around and couldn't find an answer anywhere.
I'm querying a database that has stored numbers as a VARCHAR2 data type. I'm trying to find numbers that are greater than 1450000 (where BI_SO_NBR > '1450000'), but this doesn't bring back the results I'm expecting.
I'm assuming it's because the value is stored as text and I don't know any way to get around it.
Is there some way to convert the field to a number in my query or some other trick that would work?Hopefully this makes sense.
I'm fairly new to SQL.
Thanks in advance.

If the number is too long to be converted correctly to a number, and it is always an integer with no left padding of zeroes, then you can also do:
where length(BI_SO_NBR) > length('1450000') or
(length(BI_SO_NBR) = length('1450000') and
BI_SO_NBR > '1450000'
)

You can try to use like this:
where to_number(BI_SO_NBR) > 1450000
Assuming you are using Oracle database. Also check To_Number function
EDIT:-
You can try this(after OP commented that it worked):
where COALESCE(TO_NUMBER(REGEXP_SUBSTR(BI_SO_NBR, '^\d+(\.\d+)?')), 0) > 1450000

If you are talking about Oracle, then:
where to_number(bi_so_nbr) > 1450000
However, there are 2 issues with this:
1. if there is any value in bi_so_nbr that cannot be converted to a number, this can result in an error
2. the query will not use an index on bi_so_nbr, if there is one. You could solve this by creating a function based index, but converting the varchar2 to number would be a better solution.

Related

How to extract numeric values from a column in SQL

I am trying to extract only the numeric values from a column that contains cells that are exclusively numbers, and cells that are exclusively letter values, so that I can multiply the column with another that contains only numeric values. I have tried
SELECT trim(INTENT_VOLUME)
from A
WHERE ISNUMERIC(INTENTVOLUME)
and also
SELECT trim(INTENT_VOLUME)
from A
WHERE ISNUMERIC(INTENTVOLUME) = 1
and neither works. I get the error Function ISNUMERIC(VARCHAR) does not exist. Can someone advise? Thank you!
It highly depends on DBMS.
in SqlServer you have a limited built-in features to do it, so the next query may not work with all variants of your data:
select CAST(INTENT_VOLUME AS DECIMAL(10, 4))
from A
where INTENT_VOLUME LIKE '%[0-9.-]%'
and INTENT_VOLUME NOT LIKE '%[^0-9.-]%';
In Oracle you can use regex in a normal way:
select to_number(INTENT_VOLUME)
from A
where REGEXP_LIKE(INTENT_VOLUME,'^[-+]?[0-9]+(\.[0-9]+)?$');
MySQL DBMS has also built-in regex
Try this, which tests if that text value can be cast as numeric...
select intent_volume
from a
where (intent_volume ~ '^([0-9]+[.]?[0-9]*|[.][0-9]+)$') = 't'

Manipulating a record data

I am looking for a way to take data from one table and manipulate it and bring it to another table using an SQL query.
I have a Column called NumberStuff that has data like this in it:
INC000000315482
I need to cut off the INC portion of the number and convert it into an integer and store it into a Column in another table so that it ends up looking like this:
315482
Any help would be much appreciated!
Another approach is to use the Replace function. Either in TSQL or as a Derived Column Expression in SSIS.
TSQL
SELECT REPLACE(T.MyColumn, 'INC', '') AS ReplacedINC
SSIS
REPLACE([MyColumn], "INC", "")
This removes the character based data. It then becomes an optional exercise in converting to a numeric type before storing it to the target table or letting the implicit conversion happen.
Simplest version of what you need.
select cast(right(column,6) as int) from table
Are you doing this in a SSIS statement, or?...is it always the last 6 or?...
This is a little less dependant on your formatting...removes 0's and can be any length (will trim the first 3 chars and the leading 0's).
select cast(SUBSTRING('INC000000315482',4,LEN('INC000000315482') - 3) as int)

Convert special chars to RAW format in Oracle

How do I convert a special chars like '#' to RAW format in Oracle?I need it for searching in the blob like this.
following code is giving me all rows in table as a result
dbms_lob.instr(gob_a_document, utl_raw.cast_to_raw('C#')) <> 0)
Or is there a better way?
I tried your code out, and I think it's correct for that line. On Oracle 11.2.0.1, I used your code to do something basically the same:
select v.*
from V_INCOMING_MAIL v
where dbms_lob.instr(v.message_text, utl_raw.cast_to_raw('C#'),1,1) <> 0;
This selected 9 rows out of the 15 thousand in the view. From an ad-hoc sampling of those rows and some others, that seems to be working OK.
So, perhaps the problem lies in the other lines in the SQL statement?

How to find MAX() value of character column?

We have legacy table where one of the columns part of composite key was manually filled with values:
code
------
'001'
'002'
'099'
etc.
Now, we have feature request in which we must know MAX(code) in order to give user next possible value, in example case form above next value is '100'.
We tried to experiment with this but we still can't find any reasonable explanation how DB2 engine calculates that
MAX('001', '099', '576') is '576'
MAX('099', '99', 'www') is '99' and so on.
Any help or suggestion would be much appreciated!
You already have the answer to getting the maximum numeric value, but to answer the other part with regard to 'www','099','99'.
The AS/400 uses EBCDIC to store values, this is different to ASCII in several ways, the most important for your purposes is that Alpha characters come before numbers, which is the opposite of Ascii.
So on your Max() your 3 strings will be sorted and the highest EBCDIC value used so
'www'
'099'
'99 '
As you can see your '99' string is really '99 ' so it is higher that the one with the leading zero.
Cast it to int before applying max()
For the numeric maximum -- filter out the non-numeric values and cast to a numeric for aggregation:
SELECT MAX(INT(FLD1))
WHERE FLD1 <> ' '
AND TRANSLATE(FLD1, '0123456789', '0123456789') = FLD1
SQL Reference: TRANSLATE
And the reasonable explanation:
SQL Reference: MAX
This max working well in your type definition, when you want do max on integer values then convert values to integer before calling MAX, but i see you mixing max with string 'www' how you imagine this works?
Filter integer only values, cast it to int and call max. This is not good designed solution but looking at your problem i think is enough.
Sharing the solution for postgresql
which worked for me.
Suppose here temporary_id is of type character in database. Then above query will directly convert char type to int type when it gives response.
SELECT MAX(CAST (temporary_id AS Integer)) FROM temporary
WHERE temporary_id IS NOT NULL
As per my requirement I've applied MAX() aggregate function. One can remove that also and it will work the same way.

How do I sort a VARCHAR column in PostgreSQL that contains words and numbers?

I need to order a select query using a varchar column, using numerical and text order. The query will be done in a java program, using jdbc over postgresql.
If I use ORDER BY in the select clause I obtain:
1
11
2
abc
However, I need to obtain:
1
2
11
abc
The problem is that the column can also contain text.
This question is similar (but targeted for SQL Server):
How do I sort a VARCHAR column in SQL server that contains words and numbers?
However, the solution proposed did not work with PostgreSQL.
Thanks in advance, regards,
I had the same problem and the following code solves it:
SELECT ...
FROM table
order by
CASE WHEN column < 'A'
THEN lpad(column, size, '0')
ELSE column
END;
The size var is the length of the varchar column, e.g 255 for varying(255).
You can use regular expression to do this kind of thing:
select THECOL from ...
order by
case
when substring(THECOL from '^\d+$') is null then 9999
else cast(THECOL as integer)
end,
THECOL
First you use regular expression to detect whether the content of the column is a number or not. In this case I use '^\d+$' but you can modify it to suit the situation.
If the regexp doesn't match, return a big number so this row will fall to the bottom of the order.
If the regexp matches, convert the string to number and then sort on that.
After this, sort regularly with the column.
I'm not aware of any database having a "natural sort", like some know to exist in PHP. All I've found is various functions:
Natural order sort in Postgres
Comment in the PostgreSQL ORDER BY documentation