Remove varchar data with non-numeric characters, then convert to numeric data - sql

I have a column where most values are numeric but a few contain letters or special characters:
Records
90000
5200
unknown
approximately 25 areas
TBC
5000 (approx)
I would like to remove any non-numeric entries and replace them with null like this:
Records
90000
5200
NULL
NULL
NULL
NULL
I tried to remove non-numerical characters first, then change the data to numeric:
SELECT "Year"
,regexp_replace("Records",'[%A-Za-z%+$]',NULL)
FROM records_table
However this resulted in changing all records to NULL, not just non-numeric ones.

You could try keeping the value when the field "Records" matches numbers only:
SELECT "Year",
CASE WHEN "Records" REGEXP '[0-9]+'
THEN "Records"
END
FROM records_table

Good Day, I hope this code is useful for you.
SELECT RECORDS, REGEXP_REPLACE (RECORDS, '.+[a-zA-Z]\D', 'NULL') AS RESULT
FROM (SELECT '90000' AS RECORDS FROM DUAL
UNION ALL
SELECT '5200' AS RECORDS FROM DUAL
UNION ALL
SELECT 'approximately 25 areas' AS RECORDS FROM DUAL
UNION ALL
SELECT 'TBC' AS RECORDS FROM DUAL
UNION ALL
SELECT '5000 (approx)' AS RECORDS FROM DUAL)
You can try on Regex101

Related

add two zero with decimal if number is complete integer in Oracle SQL column

Column amount contains data like - 200.203, 200, 5.10, 45.20, 10 and 5000213.012
Now I want to select if the number does not include any decimal digit then we add .00 in the returning result.
Expected result - 200.203, 200.00 ,5.10, 45.20 , 10.00 and 5000213.012
You can use TO_CHAR to format the value so that it has at least 2 decimal places:
SELECT value,
TO_CHAR( value, 'FM9999999990.009' ) AS formatted_value
FROM table_name
Which, for the sample data:
CREATE TABLE table_name ( value ) AS
SELECT 200.203 FROM DUAL UNION ALL
SELECT 200 FROM DUAL UNION ALL
SELECT 5.10 FROM DUAL UNION ALL
SELECT 45.20 FROM DUAL UNION ALL
SELECT 10 FROM DUAL UNION ALL
SELECT 5000213.012 FROM DUAL;
Outputs:
VALUE | FORMATTED_VALUE
----------: | :--------------
200.203 | 200.203
200 | 200.00
5.1 | 5.10
45.2 | 45.20
10 | 10.00
5000213.012 | 5000213.012
db<>fiddle here
Following some comments, the OP's question is effectively:
How can I change this number to have a given format?
When you consider that a NUMBER data type has no format and 5, 5.0 and 5.00000 are exactly the same value and the database does not store how many trailing zeroes a decimal value has then this question does not entirely make sense as there is no way to give a number a format.
Instead the question can be formulated as either:
How can I get <insert name of client program> to display numbers so that they always have at least 2 decimal places?
We can't answer this question without knowing the client program so I'll skip it.
Or:
How can I display a number from an Oracle query so that it is formatted with at least 2 decimal places?
Since NUMBERs never have any formatting of their own then this must involve a conversion to another data-type which can represent the number with a format (i.e. a string). So the result is that if you want a NUMBER data type then Oracle will not give it a format (but the client program might) but if you want to change the NUMBER to a string data type then you can give it a format (but it won't be a NUMBER as its now a string that just happens to contain digits) and, as described above, TO_CHAR does that.
This will do:
select to_number(to_char(value, '9999999.99')) from dual;

oracle SQL - show a number on multiple blank digits

So I'm having this problem , basicly I have a number 350 and I need to show it on 10 digits like this 350$$$$$$$ (I need to complete the number value with the character '$'). Thanks.
select rpad('350',10,'$') from dual
you can concatenate the values as $ is not number for example
select 350 ||'$' from dual

Setting a maximum value for a variable. Cognos

I started working in BI and I was given a brain teaser since I came from C# and not SQL/cognus.
I get a number. It can be between 0 and a very large number. When I get it and it's below 1,000 everything is dandy. But if it's bigger than or equal to 1,000 , I should use 1,000 instead.
I am not allowed to use conditions, I need it to be pure math, or if I can't then I should use efficient methods.
I thought it would be easy and just use Min() but that works differently in cognus and SQL apparently.
Use the LEAST() function:
Oracle Setup:
CREATE TABLE data ( value ) AS
SELECT 1 FROM DUAL UNION ALL
SELECT 999 FROM DUAL UNION ALL
SELECT 1000 FROM DUAL UNION ALL
SELECT 1001 FROM DUAL;
Query:
SELECT value, LEAST( value, 1000 ) AS output FROM data
Output:
VALUE OUTPUT
----- ------
1 1
999 999
1000 1000
1001 1000

Compare between strings in query statement in Oracle

I have this table:
id value
AA000001 500
AA000002 1000
AA000003 1500
AA000004 2000
AA000005 2500
AA000006 3000
AA000007 3500
The type of id is a string and I use below sql statement to query my record:
SELECT sum(value), max(value), min(value) FROM my_table WHERE id BETWEEN 'AA000001' AND 'AA000007'
And it's works as expected. But I wonder if there are any exceptions in this query?
I'm using Oracle 10g Release 2 and 11g Release 2.
Thanks in advances.
I'm not exactly sure what you mean by "exceptions". Your query is:
SELECT sum(value), max(value), min(value)
FROM my_table
WHERE id BETWEEN 'AA000001' AND 'AA000007';
It will match anything between these values. In addition to what is in your table, it will match, say, 'AA000003ZYW243'. You are safe that all matches will start with 'AA00000'. The next character will be between '1' and '7', and then anything can follow that (unless that character is a '7').

Why SUM(null) is not 0 in Oracle?

It would be appreciated explaining the internal functionality of SUM function in Oracle, when encountering null values:
The result of
select sum(null) from dual;
is null
But when a null value is in a sequence of values (like sum of a null-able column), the calculated value of null value will be 0
select sum(value) from
(
select case when mod(level , 2) = 0 then null else level end as value from dual
connect by level <= 10
)
is 25
This will be more interesting when seeing the result of
select (1 + null) from dual
is null
As any operation with null will result null (except is null operator).
==========================
Some update due to comments:
create table odd_table as select sum(null) as some_name from dual;
Will result:
create table ODD_TABLE
(
some_name NUMBER
)
Why some_name column is of type number?
If you are looking for a rationale for this behaviour, then it is to be found in the ANSI SQL standards which dictate that aggregate operators ignore NULL values.
If you wanted to override that behaviour then you're free to:
Sum(Coalesce(<expression>,0))
... although it would make more sense with Sum() to ...
Coalesce(Sum(<expression>),0)
You might more meaningfully:
Avg(Coalesce(<expression>,0))
... or ...
Min(Coalesce(<expression,0))
Other ANSI aggregation quirks:
Count() never returns null (or negative, of course)
Selecting only aggregation functions without a Group By will always return a single row, even if there is no data from which to select.
So ...
Coalesce(Count(<expression>),0)
... is a waste of a good coalesce.
SQL does not treat NULL values as zeros when calculating SUM, it ignores them:
Returns the sum of all the values, or only the DISTINCT values, in the expression. Null values are ignored.
This makes a difference only in one case - when the sequence being totalled up does not contain numeric items, only NULLs: if at least one number is present, the result is going to be numeric.
You're looking at this the wrong way around. SUM() operates on a column, and ignores nulls.
To quote from the documentation:
This function takes as an argument any numeric data type or any nonnumeric data type that can be implicitly converted to a numeric data type. The function returns the same data type as the numeric data type of the argument.
A NULL has no data-type, and so your first example must return null; as a NULL is not numeric.
Your second example sums the numeric values in the column. The sum of 0 + null + 1 + 2 is 3; the NULL simply means that a number does not exist here.
Your third example is not an operation on a column; remove the SUM() and the answer will be the same as nothingness + 1 is still nothingness. You can't cast a NULL to an empty number as you can with a string as there's no such thing as an empty number. It either exists or it doesn't.
Arithmetic aggregate functions ignore nulls.
SUM() ignores them
AVG() calculates the average as if the null rows didn't exist (nulls don't count in the total or the divisor)
As Bohemian has pointed out, both SUM and AVG exclude entries with NULL in them. Those entries do not go into the aggregate. If AVG treated NULL entries as zero, it would bias the result towards zero.
It may appear to the casual observer as though SUM is treating NULL entries as zero. It's really excluding them. If all the entries are excluded, the result is no value at all, which is NULL. Your example illustrates this.
This is incorrect: The sum of 0 + null + 1 + 2 is 3;
select 0 + null + 1 + 2 total from dual;
Result is null!
Similar statements give result null if any operand is null.
Here's a solution if you want to sum and NOT ignore nulls.
This solution splits the records into two groups: nulls and non-nulls. NVL2(a, 1, NULL) does this by changing all the non-nulls to 1 so they sort together identically. It then sorts those two groups to put the null group first (if there is one), then sums just the first of the two groups. If there are no nulls, there will be no null group, so that first group will contain all the rows. If, instead, there is at least one null, then that first group will only contain those nulls, and the sum of those nulls will be null.
SELECT SUM(a) AS standards_compliant_sum,
SUM(a) KEEP(DENSE_RANK FIRST ORDER BY NVL2(a, 1, NULL) DESC) AS sum_with_nulls
FROM (SELECT 41 AS a FROM DUAL UNION ALL
SELECT NULL AS a FROM DUAL UNION ALL
SELECT 42 AS a FROM DUAL UNION ALL
SELECT 43 AS a FROM DUAL);
You can optionally include NULLS FIRST to make it a little more clear about what's going on. If you're intentionally ordering for the sake of moving nulls around, I always recommend this for code clarity.
SELECT SUM(a) AS standards_compliant_sum,
SUM(a) KEEP(DENSE_RANK FIRST ORDER BY NVL2(a, 1, NULL) DESC NULLS FIRST) AS sum_with_nulls
FROM (SELECT 41 AS a FROM DUAL UNION ALL
SELECT NULL AS a FROM DUAL UNION ALL
SELECT 42 AS a FROM DUAL UNION ALL
SELECT 43 AS a FROM DUAL);