I have the below view:
CREATE OR REPLACE VIEW viewA ("col1", "col2") AS
SELECT DISTINCT CAST("col1" AS CHAR(1)),
CAST(to_char("col2",'00.0000') AS char(7))
FROM tableA
the col2 has data like 22.33 or 2.3 or 0.2345 or 2 but, four digits in dec and 2 digits in number.
It has to be written into a file with fixed length of 7 digits including decimal. Hence i wrote col2, '00.0000', but the number format'23.234' is written into col2 as 23.234 without any trailing zero.
Your format code of 00.0000 should include the fourth decimal place for 23.234; it's always worked for me. I'm using Oracle 11.
The problem I got when I tried doing CAST(TO_CHAR(23.234, '00.0000') AS CHAR(7)) was the error ORA-25137: Data value out of range. This happens because because the TO_CHAR returns a string of length 8:
SQL> SELECT '[' || TO_CHAR(23.234, '00.0000') || ']' FROM DUAL
'['||TO_CH
----------
[ 23.2340]
TO_CHAR leaves a space at the beginning in case the number is negative, in which case it will put a minus sign there. You can get rid of the leading space by using the FM modifier in the format string:
SQL> SELECT '[' || TO_CHAR(23.234, 'FM00.0000') || ']' FROM DUAL
'['||TO_CH
----------
[23.2340]
This is all a long way of saying "try this instead" - the only change is the FM in the TO_CHAR format string:
CREATE OR REPLACE VIEW viewA ("col1", "col2") AS
SELECT DISTINCT
CAST("col1" AS CHAR(1)),
CAST(to_char("col2",'FM00.0000') AS char(7))
FROM tableA
One final note: enclosing the column names with double quotes makes them case sensitive, and that often leads to trouble. I'd recommend losing the double quotes if you can.
You need to use the RPAD function that would add trailing zeros for you
CREATE OR REPLACE VIEW viewA ("col1", "col2") AS
SELECT DISTINCT CAST("col1" AS CHAR(1)),
RPAD(CAST(to_char("col2",'00.0000') AS char(7)),7,'0')
FROM tableA
But you might face a problem if your number did not have a decimal value, for example assuming the value is 12 you will end up with 1200000 but maybe this would give you an idea
Related
I have a column in a table ident_nums that contains different types of ids. I need to remove special characters(e.g. [.,/#&$-]) from that column and replace them with space; however, if the special characters are found at the beginning of the string, I need to remove it without placing a space. I tried to do it in steps; first, I removed the special characters and replaced them with space (I used
REGEXP_REPLACE) then found the records that contain spaces at the beginning of the string and tried to use the TRIM function to remove the white space, but for some reason is not working that.
Here is what I have done
Select regexp_replace(id_num, '[:(),./#*&-]', ' ') from ident_nums
This part works for me, I remove all the unwanted characters from the column, however, if the string in the column starts with a character I don't want to have space in there, I would like to remove just the character, so I tried to use the built-in function TRIM.
update ident_nums
set id_num = TRIM(id_num)
I'm getting an error ORA-01407: can't update ident_nums.id_num to NULL
Any ideas what I am doing wrong here?
It does work if I add a where clause,
update ident_nums
set id_num = TRIM(id_num) where id = 123;
but I need to update all the rows with the white space at the beginning of the string.
Any suggestions are welcome.
Or if it can be done better.
The table has millions of records.
Thank you
Regexp can be slow sometimes so if you can do it by using built-in functions - consider it.
As #Abra suggested TRIM and TRANSLATE is a good choice, but maybe you would prefer LTRIM - removes only leading spaces from string (TRIM removes both - leading and trailing character ). If you want to remove "space" you can ommit defining the trim character parameter, space is default.
select
ltrim(translate('#kdjdj:', '[:(),./#*&-]', ' '))
from dual;
select
ltrim(translate(orginal_string, 'special_characters_to_remove', ' '))
from dual;
Combination of Oracle built-in functions TRANSLATE and TRIM worked for me.
select trim(' ' from translate('#$one,$2-zero...', '#$,-.',' ')) as RESULT
from DUAL
Refer to this dbfiddle
I think trim() is the key, but if you want to keep only alpha numerics, digits, and spaces, then:
select trim(' ' from regexp_replace(col, '[^a-zA-Z0-9 ]', ' ', 1, 0))
regexp_replace() makes it possible to specify only the characters you want to keep, which could be convenient.
Thanks, everyone, It this query worked for me
update update ident_nums
set id_num = LTRIM(REGEXP_REPLACE(id_num, '[:space:]+', ' ')
where REGEXP_LIKE(id_num, '^[ ?]')
this should work for you.
SELECT id_num, length(id_num) length_old, NEW_ID_NUM, length(NEW_ID_NUM) len_NEW_ID_NUM, ltrim(NEW_ID_NUM), length(ltrim(NEW_ID_NUM)) length_after_ltrim
FROM (
SELECT id_num, regexp_replace(id_num, '[:(),./#*&-#]', ' ') NEW_ID_NUM FROM
(
SELECT '1234$%45' as id_num from dual UNION
SELECT '#SHARMA' as id_num from dual UNION
SELECT 'JACK TEST' as id_num from dual UNION
SELECT 'XYZ#$' as id_num from dual UNION
SELECT '#ABCDE()' as id_num from dual -- THe 1st character is space
)
)
Some of the column values in my table are enclosed within double quotes and I need to remove those double quotes. The problem is, I am not able to view the double quotes symbol in SQL Developer (version 4.2.0.16.260). But when I copy the data to Notepad++, there I am getting double quotes. I tried instr to get the position of double quotes, its returning the result 0. Also I tried to replace double quotes with blank, but they are not being removed.
Below is the data I see when copied to Notepad++. 2 records are displayed. I'm trying to take the distinct value from these 2 values. But I am not able to.
"Testdata
"
Testdata
The column value in the database table does not have double quotes.
When you copy the data from the results grid, SQL Developer is adding them as part of the copy operation, to help you out. (There's probably way to ask it not to, but I can't immediately see one.) It's doing that because the first value you're getting has a trailing new line character. I can duplicate what you're seeing if I do:
select 'Testdata' || chr(10) from dual
union all
select 'Testdata' from dual;
If I run as a script, the script output window shows:
'TESTDATA
---------
Testdata
Testdata
Here the newline is lost, and copy and pasting from that doesn't preserve it. If I run as a statement the data in the query result window looks the same:
but if I copy that data from the grid and paste it (anywhere, not just in Notepad++) I also see:
"Testdata
"
Testdata
... so the newline is preserved, and is enclosed in double-quotes so whatever it is pasted into (I'm guessing this is targeted at Excel) understands that it is a single value, including that newline character.
Im trying to take the distinct value from these 2 values
The problem is that they are not, in fact, distinct; one has a newline, the other does not.
If you want to ignore that and treat them as the same you can trim off the trailing newline:
select distinct rtrim(col, chr(10))
from your_table;
Demo with the same sample data:
-- CTE for sample data
with your_table (col) as (
select 'Testdata' || chr(10) from dual
union all
select 'Testdata' from dual
)
select col
from your_table;
COL
---------
Testdata
Testdata
-- CTE for sample data
with your_table (col) as (
select 'Testdata' || chr(10) from dual
union all
select 'Testdata' from dual
)
select distinct rtrim(col, chr(10)) as col
from your_table;
COL
---------
Testdata
Please try this out
SELECT REPLACE(TRIM(column_name), CHR(13)||CHR(10))
FROM table_name;
I need to give format to the following number:
1234567.89
as
1 234 567.89
I already tried:
select regexp_replace( '1234567.89', '(...)', '\1 ' ) from dual;
But its starting from left to right the counting and it's ignoring the decimal dot.
Thanks in advance.
Best regards.
SELECT TO_CHAR(10000,'99G999D99MI',
'NLS_NUMERIC_CHARACTERS = ''. ''
NLS_CURRENCY = '' ') "Amount"
FROM DUAL;
you can do it like this
select replace(to_char(1234567.89, '9,999,999,999,999,999.99'), ',', ' ') x from dual
Only in this case, you need to know how big is the biggest number you will have. If lets say, your biggest number is in millions, make format model in billions, so it covers either exact number of digits or more
I want to add zeroes after the number .
for eg a= 6895
then a= 6895.00
datatype of a is number(12);
I am using the below code .
select to_char(6895,'0000.00') from dual .
I m getting the desired result from above code but
'6895' can be any number.so due to that i need to add '0' in above code manually.
for eg.
select to_char(68955698,'00000000.00') from dual .
Can any one suggest me the better method .
The number format models are the place to start when converting numbers to characters. 0 prepends 0s, which means you'd have to get rid of them somehow. However, 9 means:
Returns value with the specified number of digits with a leading space if positive or with a leading minus if negative. Leading zeros are blank, except for a zero value, which returns a zero for the integer part of the fixed-point number.
So, the following gets you almost there, save for the leading space:
SQL> select to_char(987, '9999.00') from dual;
TO_CHAR(
--------
987.00
You then need to use a format model modifier, FM, which is described thusly:
FM Fill mode. Oracle uses trailing blank characters and leading zeroes
to fill format elements to a constant width. The width is equal to the
display width of the largest element for the relevant format model
...
The FM modifier suppresses the above padding in the return value of
the TO_CHAR function.
This gives you a format model of fm9999.00, which'll work:
SQL> select to_char(987, 'fm9999.00') from dual;
TO_CHAR(
--------
987.00
If you want a lot of digits before the decimal then simply add a lot of 9s.
datatype of a is number(12);
Then use 12 9s in the format model. And, keep the decimal to just 2. So, since the column datatype is NUMBER(12), you cannot have any number more than the given size.
SQL> WITH DATA AS(
2 SELECT 12 num FROM dual union ALL
3 SELECT 234 num FROM dual UNION ALL
4 SELECT 9999 num FROM dual UNION ALL
5 SELECT 123456789 num FROM dual)
6 SELECT to_char(num,'999999999999D99') FROM DATA
7 /
TO_CHAR(NUM,'999
----------------
12.00
234.00
9999.00
123456789.00
SQL>
Update Regarding leading spaces
SQL> select ltrim(to_char(549,'999999999999.00')) from dual;
LTRIM(TO_CHAR(54
----------------
549.00
SQL>
With using CASE and SUBSTR it is very simple.
CASE WHEN SUBSTR(COLUMN_NAME,1,1) = '.' THEN '0'||COLUMN_NAME ELSE COLUMN_NAME END
Given data in a column which look like this:
00001 00
00026 00
I need to use SQL to remove anything after the space and all leading zeros from the values so that the final output will be:
1
26
How can I best do this?
Btw I'm using DB2
This was tested on DB2 for Linux/Unix/Windows and z/OS.
You can use the LOCATE() function in DB2 to find the character position of the first space in a string, and then send that to SUBSTR() as the end location (minus one) to get only the first number of the string. Casting to INT will get rid of the leading zeros, but if you need it in string form, you can CAST again to CHAR.
SELECT CAST(SUBSTR(col, 1, LOCATE(' ', col) - 1) AS INT)
FROM tab
In DB2 (Express-C 9.7.5) you can use the SQL standard TRIM() function:
db2 => CREATE TABLE tbl (vc VARCHAR(64))
DB20000I The SQL command completed successfully.
db2 => INSERT INTO tbl (vc) VALUES ('00001 00'), ('00026 00')
DB20000I The SQL command completed successfully.
db2 => SELECT TRIM(TRIM('0' FROM vc)) AS trimmed FROM tbl
TRIMMED
----------------------------------------------------------------
1
26
2 record(s) selected.
The inner TRIM() removes leading and trailing zero characters, while the outer trim removes spaces.
This worked for me on the AS400 DB2.
The "L" stands for Leading.
You can also use "T" for Trailing.
I am assuming the field type is currently VARCHAR, do you need to store things other than INTs?
If the field type was INT, they would be removed automatically.
Alternatively, to select the values:
SELECT (CAST(CAST Col1 AS int) AS varchar) AS Col1
I found this thread for some reason and find it odd that no one actually answered the question. It seems that the goal is to return a left adjusted field:
SELECT
TRIM(L '0' FROM SUBSTR(trim(col) || ' ',1,LOCATE(' ',trim(col) || ' ') - 1))
FROM tab
One option is implicit casting: SELECT SUBSTR(column, 1, 5) + 0 AS column_as_number ...
That assumes that the structure is nnnnn nn, ie exactly 5 characters, a space and two more characters.
Explicit casting, ie SUBSTR(column,1,5)::INT is also a possibility, but exact syntax depends on the RDBMS in question.
Use the following to achieve this when the space location is variable, or even when it's fixed and you want to make a more robust query (in case it moves later):
SELECT CAST(SUBSTR(LTRIM('00123 45'), 1, CASE WHEN LOCATE(' ', LTRIM('00123 45')) <= 1 THEN LEN('00123 45') ELSE LOCATE(' ', LTRIM('00123 45')) - 1 END) AS BIGINT)
If you know the column will always contain a blank space after the start:
SELECT CAST(LOCATE(LTRIM('00123 45'), 1, LOCATE(' ', LTRIM('00123 45')) - 1) AS BIGINT)
both of these result in:
123
so your query would
SELECT CAST(SUBSTR(LTRIM(myCol1), 1, CASE WHEN LOCATE(' ', LTRIM(myCol1)) <= 1 THEN LEN(myCol1) ELSE LOCATE(' ', LTRIM(myCol1)) - 1 END) AS BIGINT)
FROM myTable1
This removes any content after the first space character (ignoring leading spaces), and then converts the remainder to a 64bit integer which will then remove all leading zeroes.
If you want to keep all the numbers and just remove the leading zeroes and any spaces you can use:
SELECT CAST(REPLACE('00123 45', ' ', '') AS BIGINT)
While my answer might seem quite verbose compared to simply SELECT CAST(SUBSTR(myCol1, 1, 5) AS BIGINT) FROM myTable1 but it allows for the space character to not always be there, situations where the myCol1 value is not of the form nnnnn nn if the string is nn nn then the convert to int will fail.
Remember to be careful if you use the TRIM function to remove the leading zeroes, and actually in all situations you will need to test your code with data like 00120 00 and see if it returns 12 instead of the correct value of 120.