oracle regex_replace to keep digit and backslash - sql

I have excel file that contains some junk data in date field.
the date format is in 1/2/2015 format. I'm trying to load that file into a stage table in varchar field and apply regex replace function to clean up the bad data before loading to main table
can i somebody provide me the suitable experssion for this
create table A
(
bad_date varchar2(4000)
);
insert into A
( bad_date)
values ('1/2/2005');
insert into A
( bad_date)
values ('indep');
insert into A
( bad_date)
values ('/');
commit;
create table B
(
good_date date
);
I want to use regex function to cleanse the data which is not in the date pattern. Thanks for your help!

Use ^[0-9]{1,2}/[0-9]{1,2}/[0-9]{4} pattern for regexp_like conforming your date format.
Use the following insert statement to get clean date data :
insert into B
select * from
( select to_date(bad_date,
case when
regexp_like(bad_date,'^[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}') then
'DD/MM/YYYY'
end) dateConverted
from A)
where dateConverted is not null;
SQL Fiddle Demo

You can come close with something like:
select (case when regexp(bad_date, '^[0-1]?[0-9]/[0-3]?[0-9]/[0-9]{4}$')
then to_date(bad_date, 'MM/DD/YYYY'
end) as converted_date

Use the following:
INSERT INTO B (GOOD_DATE)
SELECT TO_DATE(BAD_DATE, 'DD/MM/YYYY')
FROM A
WHERE REGEXP_LIKE(BAD_DATE, '[0-9]+/[0-9]+/[0-9]+')
SQLFiddle here
Best of luck.

I am inclined to contribute a more mature regex to match valid dates in m/d/yyyy format:
INSERT INTO B (GOOD_DATE)
SELECT TO_DATE(BAD_DATE, 'DD/MM/YYYY')
FROM A
WHERE REGEXP_LIKE(BAD_DATE,
'^(0?[1-9]|[12][0-9]|3[01])\/(0?[1-9]|1[012])\/(19|20)[0-9][0-9]$'
)
SQLFiddle
Inspired by
Regex to validate dates in this format d/m/yyyy
https://www.regular-expressions.info/dates.html

Related

Is there any way to output the result of a column of each row to show a different value in OracleDB using PL/SQL?

I have a Select Statement that has a column which is a code value. For e.g. instead of Java its JV, and instead of Python its PY. However, instead of outputting the coded value, I would like to display them as Java or Python i.e. their full description. Is there a way to do this with PL/SQL?
Any help would be greatly appreciated, thanks!
you can use case expression
select
case
when myColumn = 'JV' then 'Java'
when myColumn = 'PY' then 'Python'
end as myColumn
from yourTable
In oracle you can use decode as well.
decode(col, 'JV', 'Java',
'PY', 'Python'
'No Match'
)
Given that you are using Oracle, I would recommend using the DECODE function:
SELECT
col,
DECODE(col, 'JV', 'Java',
'PY', 'Python',
'Not found') AS col_out
FROM yourTable;
You can use either the "DECODE" function, or a "CASE" construct, as follows:
select DECODE(my_column,
'JV','Java',
'PY','Python',
'no_match_found') my_column_alias
from my_table;
select
case my_column
when 'JV' then 'Java'
when 'PY' then 'Python'
else 'no_match_found'
end my_column_alias
from my_table;
While there are several ways of hard coding the for the sample data given none are the proper method for more than a very limited set. The proper method is to create a lookup table. In this case contains the code and corresponding name. Yes, it is quite overkill for 2 languages, but how about the TIOBE Index or the 700 listed in Wikipedia, or the estimated approximately 9000 claimed in the HOPL list. See here and additional links more.
Moreover it is a standard technique to OP underlying question: Is there a way to give detail about a given code value.
It is easily extended (just add row to a table) and applicable across virtually all domains (abet with slight modifications).
-- create language lookup
create table language_lookup(
code varchar2(8)
, name varchar2(200)
, description varchar2(4000)
, constraint language_lookup_pk
primary key (code)
);
insert into language_lookup(code, name)
select 'JV','Java' from dual union all
select 'PY','Python' from dual ;
-- your table
create table your_table ( id integer
, lang_code varchar2(8)
--...
, constraint your_table_pk
primary key (id)
, constraint your_table_2_language_lookup_fk
foreign key (lang_code)
references language_lookup(code)
) ;
insert into your_table (id, lang_code)
select 1,'JV' from dual union all
select 2,'PY' from dual;
select yt.lang_code, ll.name
from your_table yt
join language_lookup ll
on ll.code = yt.lang_code
where yt.lang_code in ('JV','PY')
;
-- now modify to include plsql
insert into language_lookup(code, name)
values ( 'PLSQL', 'Oracle''s Programming Language extension for SQL');
insert into your_table (id,lang_code)
values (3,'PLSQL');
select yt.lang_code, ll.name
from your_table yt
join language_lookup ll
on ll.code = yt.lang_code
;
Try that with your hard coded values. Then add 30 - 40 more ...

Select query not records any data when date is used in where clause

I have a table as below
CREATE TABLE TEST
( TEST_ID NUMBER(9,0) DEFAULT NULL,
TEST_DESC VARCHAR2(30 BYTE),
TEST_DATE DATE);
I have inserted the data as follows
1 sample1 28-07-18
2 sample2 29-07-18
3 sample3 30-07-18
4 sample4 31-07-18
5 sample5 01-08-18
when I try to select the records from table TEST by using TEST_DATE as a where clause.
select * from TEST where TEST_DATE = '01-08-18'
select * from TEST where TEST_DATE = TO_DATE('2018-08-01','YYYY-MM-DD')
the above queries returning empty set as output.
Please help me out in this.
Thanks in advance
Date type in Oracle also stores the time. So probably your query doesn't work because of different time parts.
Use this query to get the full view of the Date values:
SELECT TEST_ID, TEST_DESC, TO_CHAR(TEST_DATE, 'yy.mm.dd HH24:MI:SS') FROM TEST;
could be due to the NLS settings in your database,
do a select * from test and see how the output is.
then either change your NLS settings for update your query accordingly to match that.
]2
try adding TRUNC:
select * from TEST where trunc(TEST_DATE) = trunc(TO_DATE('2018-08-01','YYYY-MM-DD'))
First, you can use date constants. So:
where TEST_DATE = DATE '2018-08-01'
If this doesn't work, then you probably inserted data from another century and you should fix the data. You can try this:
select extract(year from test_date), t.test_date
from t
where extract(year from test_date) < 2000
You can fix the data in place (by adding years) or by re-importing the data.
So, use four-digit years. That is what the year values are.

remove left characters in sql oracle

I have a varchar column with some data like: 0000000000,0000000123,0000000010,...
I want to cast this column into an integer, but I get the error it is not a number. So I thought I have to remove the left 0 of the varchar, but how do I do that?
I'm not sure what your problem is. Both these work when I try them:
select cast('0000000123' as int), to_number('0000000123')
from dual;
Here is a rextester illustrating that this works in Oracle.
use to_number function
select to_number('000001') from dual it will return 1
so your case
select to_number(column) from your_table

How to select all values and hide NULL values in SQL?

so in my database some rows have NULL values, and when I select * from table, that NULL values also shows as text "null". So I want to hide all NULL values. Does anyone have idea for query? Thanks!
this is my input in DB:
db.execSQL("CREATE TABLE IF NOT EXISTS table (name VARCHAR, kg VARCHAR, pod VARCHAR,reps VARCHAR, time VARCHAR );");
db.execSQL("INSERT INTO table VALUES('name 1',NULL,NULL , NULL , '"+s+"');");
db.execSQL("INSERT INTO table VALUES(NULL,'S 1','"+ee5+"' , '"+ee+"' , '"+s+"');");
db.execSQL("INSERT INTO table VALUES(NULL,'S 2','"+ee6+"' , '"+ee2+"', '"+s+"');");
db.execSQL("INSERT INTO table VALUES(NULL,'S 3','"+ee7+"' , '"+ee3+"', '"+s+"');");
db.execSQL("INSERT INTO table VALUES(NULL,'S 4','"+ee8+"' , '"+ee4+"', '"+s+"');");
It depends on the data type of the column.
-- If the data type is integer:
SELECT COALESCE(the_column, 0)
FROM the_table;
-- or, if the column is a char or varchar type:
SELECT COALESCE(the_column, 'some text here')
FROM the_table;
-- or, if it is a date:
SELECT COALESCE(the_column, '1900-01-01')
FROM the_table;
BTW: some databases have the IFNULL() function which does the same thing.
This is what you are looking for:
SELECT x, y, etc, CASE WHEN field IS NOT NULL THEN field ELSE '' END AS hehe FROM table;
Edit: Addin to your comments, this is pretty trivial once you know how to do it for one column. Apply the same for all columns. In SO dont expect homeworks to get done, instead expect a help to solve your problem which ultimately you yourself have to do.
Btw, here is how..
SELECT COALESCE(name, ''), COALESCE(kg, ''), COALESCE(pod, ''), COALESCE(reps, ''),
COALESCE(time, '')
FROM table
You have three good methods in this thread (including mine), and I personally feel the other two are more intuitive. Use any by applying the same logic as I have shown.
in SQLite you should be able to do something like this:
SELECT col1, col2, ..., ifnull(coln, '') FROM TABLE
SELECT* FROM TableName
WHERE ValueCol IS NOT NULL
http://www.w3schools.com/sql/sql_null_values.asp
if you're working with sqlite for android
look at this Article

setting data types in MS ACCESS SQL Insert queries

How can we explicitly convert data types in INSERT INTO/SELECT queries in MS Access?
Sample Query:
INSERT INTO pStudents( pStudentID, pDate, pRate, pGrade )
SELECT sStudentID, sDate, sRate, sGrade
FROM sStudents
WHERE (((sStudents.sStudentID) Is Not Null);
Here I want to convert fields from sStudents table before inserting in pStudents to following:
pStudentID = text
pDate = Short Date
pRate = Double
pGrade = text
Thanks in advance
You can use the built-in conversion functions of Access in the queries:
Select CStr(NumericColumn) from Table
...or as an INSERT query:
Insert Into AnotherTable (StringColumn)
Select CStr(NumericColumn) from Table
Did you mean something like that?
EDIT:
Okay, your sample query with conversions would look like this:
INSERT INTO pStudents( pStudentID, pDate, pRate, pGrade )
SELECT CStr(sStudentID), CDate(sDate), CDbl(sRate), CStr(sGrade)
FROM sStudents
WHERE (((sStudents.sStudentID) Is Not Null);
However, this will only work if the columns contain only data that can actually be converted into the given type.
For example, you can convert a String column to Double with CDbl() - but only if the selected rows contain only values that can actually be converted into Double.
As soon as you select one row with a value that contains something else than numeric values (like 'hello'), the conversion will fail.
On the other hand, do you really need the conversions?
Access can convert a lot by itself. For example, you can insert values from a numeric column into a string column, Access will convert it by itself. You don't have to use CStr() for that.
This should work. If you want Date, you can use CDate, however this will make sure the date is a short date (http://www.techonthenet.com/access/functions/date/format.php)
INSERT INTO pStudents( pStudentID, pDate, pRate, pGrade )
SELECT CStr(sStudentID), Format(sDate, "Short Date"), CDbl(sRate), CStr(sGrade)
FROM sStudents WHERE (((sStudents.sStudentID) Is Not Null);
There are many conversion function that are available in Access.
CBool(expression)
CByte(expression)
CCur(expression)
CDate(expression)
CDbl(expression)
CDec(expression)
CInt(expression)
CLng(expression)
CSng(expression)
CStr(expression)
CVar(expression)
http://office.microsoft.com/en-us/access-help/type-conversion-functions-HA001229018.aspx
Then you would use these functions in your INSERT INTO/SELECT query:
INSERT INTO table1 (field)...
SELECT Cstr(fieldValue)...
FROM table2
If you need to convert each of the fields in sStudents, then based on your edit you could do the following:
INSERT INTO pStudents( pStudentID, pDate, pRate, pGrade )
SELECT CStr(sStudentID), CDate(sDate), CDbl(sRate), CStr(sGrade)
FROM sStudents
WHERE (((sStudents.sStudentID) Is Not Null);