How can I alter data type and datas in it, numbers separated with comma - sql

I have table , that has field named AMOUNT , amount takes number, table has 1.4m records, i need to upgrade them all . I would like the change NUMBER to varchar and make look like amount datas comma separated , eg: 76543-> 76,543. How can I able to do it?

1 - Create the new column at the end of the table.
2 - Run an update to populate the new table column
(in this step for thousand seperataor look Thousand Seperator function in oracle? )
3 - Drop the old table column
4 - Re-name the new column to the original column name

i need to upgrade them all
Don't; if you have a numeric value then store it as a NUMBER.
I would like the change NUMBER to varchar and make look like amount datas comma separated , eg: 76543-> 76,543. How can I able to do it?
Just change how you are displaying the value rather than changing how you are storing the value.
If you have the table and data:
CREATE TABLE table_name ( amount NUMBER(12,0) );
INSERT INTO table_name ( amount ) VALUES ( 76543 );
If you want to do it in a SELECT statement then use TO_CHAR and include sufficient digits to format the largest number you can hold:
SELECT amount,
TO_CHAR(amount, 'FM999G999G999G990') AS formatted_amount
FROM table_name;
Outputs:
AMOUNT
FORMATTED_AMOUNT
76543
76,543
If you want to do that in the table then add a virtual column:
ALTER TABLE table_name
ADD formatted_amount VARCHAR2(16)
GENERATED ALWAYS AS ( TO_CHAR(amount, 'FM999G999G999G990') );
Then, after adding the virtual column:
SELECT * FROM table_name;
Outputs:
AMOUNT
FORMATTED_AMOUNT
76543
76,543
db<>fiddle here

You can use to_char():
select to_char(col, 'FM999,990;')

Related

Change Schema while creating table

I have an issue later in my process when I want the append tables with a different Datatypes.
I am creating a new table out of an existing table. One column is the Calenderweek(KW) which was originally a STRING. In order to append my tables later on I need the same datatype for the column.
Is there a way to change the datatype for a column while creating the new table?
CREATE TABLE IF NOT EXISTS
MyNewTable
AS(
SELECT
Column_1 AS
Column_1_alias,
**KW_ AS KW,**
FROM
SourceTable);
What this Query does is that it only grabs the value of the column KW that contains a number, then checks if the STRING value contains a character and removes it from the STRING. Finally it CAST to the desired value type of the column, so it ends as an INT.
CREATE TABLE IF NOT EXISTS
dataset.MyNewTable
AS(
SELECT
Column1 AS
Column1_alias,
CAST(REGEXP_REPLACE(KW,'[^0-9^]','') as INT64) as KW_Alias
FROM
`project.dataset.source`
WHERE REGEXP_CONTAINS(KW,'[0-9]')
);
Another possible solution is to use the function REPLACE instead of REGEXP_REPLACE, to replace the string to a number.

Sum with two column is SQL Oracle

I have two columns in a SQL table and I need a third column with the sum of the other two.
It's possible to add a calculated column?
SELECT WRAP_DURATION, IS_SERV_TYP_FLAG,
FROM RVM_DM.FACT_INTERACTION_SEGMENT
Yes it is possible. I did this in the following query, of course, if the columns are numeric
SELECT Col1,Col2,SUM(Col1 + Col2) AS Column3
FROM yourTable
GROUP BY Col1,Col2
If you want to combine two columns, use the following query
SELECT Col1,Col2,CONCAT(Col1,' ', Col2) AS Column3,
FROM yourTable
Example
SELECT Col1,Col2,nvl(Col1,0) + nvl(Col2,0) AS Column3
FROM yourTable
Try this
SELECT WRAP_DURATION, IS_SERV_TYP_FLAG, NVL(WRAP_DURATION,0) + NVL(IS_SERV_TYP_FLAG,0) SUM_OF_TWO_COL
FROM RVM_DM.FACT_INTERACTION_SEGMENT
Oracle supports generated columns, so you can just add this to the table:
ALTER TABLE RVM_DM.FACT_INTERACTION_SEGMENT ADD calculated INT
GENERATED ALWAYS AS (WRAP_DURATION + IS_SERV_TYP_FLAG);
This becomes part of the table definition -- and the value is always correct because it is calculated when it is queried.
I will say that it seems odd to add a flag to a duration, but this works for most expressions that use only columns in one row (or constants).
Oracle offered a virtual column you do with this.
syntax of a virtual column:
column_name [data_type] [GENERATED ALWAYS] AS (expression) [VIRTUAL]
In this syntax:
First, specify the name ( column_name) of the virtual column.
Second, specify the virtual column’s data type. If you omit the data type, the virtual column will take the data type of the result of the expression.
Third, specify an expression in parentheses after the AS keyword. The values of the virtual column will derive from the expression.
1) Creating a table with a virtual column example
create table RVM_DM.FACT_INTERACTION_SEGMENT (
WRAP_DURATION number,
IS_SERV_TYP_FLAG number,
CALC_SUM number generated always as (NVL(WRAP_DURATION,0) + NVL(IS_SERV_TYP_FLAG,0)) virtual
);
2) Adding a virtual column to an existing table example
ALTER TABLE RVM_DM.FACT_INTERACTION_SEGMENT
ADD (
CALC_SUM AS (NVL(WRAP_DURATION,0) + NVL(IS_SERV_TYP_FLAG,0))
);

Want to insert data in oracle number data type column as '001' instead of '1'

Want to insert data in oracle number data type column as '001' instead of '1'.
Here is my code:
create table TEMP2 (id number);
INSERT INTO TEMP2 VALUES(001);
When executing:
SELECT * FROM TEMP2;
The output appears as:
ID
1
I want to store number as '001' instead of '1'.
You shouldn't store information that is only used for display purposes. If that is a number, then by all means store it as a number.
You can always format the output when displaying the values:
SELECT to_char(id, 'FM000')
FROM TEMP2;
If you don't want to do that each time you run a select, create a view:
create view formatted_temp
as
SELECT to_char(id, 'FM000')
FROM TEMP2;
Or create a computed column that does that for you:
alter table temp2
add formatted_id generated always as (to_char(id, 'FM000'));
You can change the column to VARCHAR2. Wether this is a good solution depends on your needs

How to create alphanumeric sequence using date and sequence number

I want to create an alphanumeric sequence in oracle. Table name is rel_details it consists of four columns.
rel_id
rel_name
rel_modified_date
rel_desc
In rel_id i want to generate ID like REL230420151001
REL is a string ,
23042015 is today's date,
1001 is a starting number.
How to create this type sequence.
If you are on 12c, then here is one way using IDENTITY column and VIRTUAL column.
Identity column was introduced in version 12c, and virtual column was introduced in version 11g.
SQL> CREATE TABLE t
2 (
3 ID NUMBER GENERATED ALWAYS AS IDENTITY
4 START WITH 1000 INCREMENT BY 1,
5 text VARCHAR2(50),
6 dt DATE DEFAULT SYSDATE,
7 my_text varchar2(1000) GENERATED ALWAYS AS (text||to_char(dt, 'DDMMYYYY')||ID) VIRTUAL
8 );
Table created.
SQL>
SQL> INSERT INTO t(text) VALUES ('REL');
1 row created.
SQL>
SQL> SELECT text, my_text FROM t;
TEXT MY_TEXT
----- ------------------------------
REL REL230420151000
SQL>
I created identity column to start with 1000, you could customize the way you want.
There is one small trick about the VIRTUAL column. You will have to explicitly cast it as varchar2 with fixed size, else the implicit conversion will make it up to maximum size. See this for more details Concatenating numbers in virtual column expression throws ORA-12899: value too large for column
if I were you, I wouldn't bother storing such a sequence in a column; I would store the columns containing the relevant information separately and then either have a virtual column that concatenates them together or do the concatenating in a view.
Check this , you may not able to create seq , but you can use select as below.
create sequence mysec
minvalue 0
start with 10001
increment by 1
nocache;
select 'REL'||to_char(sysdate,'DDMMYYYY')||mysec.nextval from dual;

Create column from other columns in Database

I have a table name: test
ID | Prefix | ACCID
ID's type is INTEGER which is selected from ID_SEQ
Prefix's type is VARCHAR(6)
ACCID is the combination of Prefix + ID
I want to auto-create ACCID when I insert the ID and Prefix value such as
INSERT INTO TEST (PREFIX) VALUES ('A01407V');
and the database store the ACCID as 'A01407V000001'
I create the sequence as
CREATE SEQUENCE ID_SEQ AS INT MAXVALUE 999999 CYCLE;
How to implement SQL statement to produce this result?
Thank you for all solutions and suggestions.
Ps. I use Apache Derby as my SQL Server
As documented in the manual, Derby supports generated columns (since Version 10.5)
The real problem is the formatting of a number with leading zeros as Derby has no function for that.
If you really, really think you need to store a value that can always be determined by the values already stored in the table, you can use something like this:
create table test
(
id integer,
prefix varchar(6),
accid generated always as (prefix||substr('000000', 1, 6 - length(rtrim(char(id))))||rtrim(char(id)))
);
The expression substr('000000', 1, 6 - length(rtrim(char(id))))||rtrim(char(id)) is just a complicated way to format a the ID with leading zeros.
I would highly recommend to not store this value though. It is much cleaner to create a view that shows this value if you do need access to this in SQL.
You can use COMPUTED Column.
Is a computed column that is based on some other column in the table. We can physically save the data of the column/ or not. Table will automatically update the value of this column.
syntax:
columnname AS expression [PERSISTED]
--PERSISTED will make it physically saved, otherwise it will be calculated every time.
We can create indexes on computed columns.
You add, The following in the table CREATE Script
ACCID AS Prefix + CAST(ID AS CHAR(6)) [PERSISTED]