Convert 'NULL' to Date in SQL - sql

I have a column in my table called startdate. It is in string format. Most of the fields are 'NULL'. I am copying this column to another table which data type is 'Date'.
How can I convert all the values from string to Date in SQL.
I have tried this code:
INSERT INTO Destination_Table [new_date]
SELECT CONVERT(DATE,[startdate],103)
FROM Source_Table

nullif([startdate],'NULL') returns [startdate] unless it equals to 'NULL' and then it returns NULL (a real NULL, not the string 'NULL')
INSERT INTO Destination_Table [new_date]
SELECT CONVERT(DATE,nullif([startdate],'NULL'),103)
from Source_Table
For learning purposes, here are some expressions with the same results:
nullif(x,y)
case when x=y then null else x end
case x when y then null else x end

It looks like you are using MSSQL. If you are using MSSQL 2012, the following code should work :
INSERT INTO Destination_Table [new_date]
SELECT IIF([startdate] = "NULL", null, CONVERT(DATE,[startdate],103))
FROM Source_Table
What this does, is use the IIF() method to check the value of [startdate] and if the value is the text "NULL", then return the actual null value which can be allowed in most fields unless you have null disabled on the Destination_Table.[new_date] field.
Since the Date field can only accept and store Date/Time/Date&Time/(actual null) information, the text "NULL" is not valid.
Following is the equivalent for MySQL
INSERT INTO Destination_Table [new_date]
SELECT IF([startdate] == 'NULL', null, CONVERT(DATE,[startdate],103))
FROM Source_Table
(although I am unsure MySQL allows a conversion code as a param to CONVERT() )

Related

Snowflake: Insert null value in a numeric type column

I have a case statement to rectify one business logic in snowflake:
INSERT INTO DB.table_b
SELECT
CASE
WHEN UPPER(emp) <> LOWER(emp) THEN NULL
WHEN emp IS NULL THEN nullif(emp, 'NULL')
ELSE emp
END AS emp_no
FROM
DB.table_a;
The 'table_a' content as below :
emp
-------
ABCD
NULL
''
23
It contains character string, null, empty and numbers. So, the requirement is to take only numbers and empty values from the case statement since the column emp_no in 'table_b' is numeric type. In source table if the column value is string then we have to insert NULL value. But as the 'table_b' column is of type 'numeric' the null value is not getting inserted and getting following error
Numeric value '' is not recognized
Using TRY_TO_NUMBER:
A special version of TO_DECIMAL , TO_NUMBER , TO_NUMERIC that performs the same operation (i.e. converts an input expression to a fixed-point number), but with error-handling support (i.e. if the conversion cannot be performed, it returns a NULL value instead of raising an error).
INSERT INTO DB.table_b
SELECT TRY_TO_NUMBER(emp) AS emp
FROM DB.table_a;
you can not use IS_INTEGER but for VARCHAR(16777216) it isn't supported
So a regular expression would be better
INSERT INTO DB.table_b
SELECT
CASE
WHEN regexp_like(emp,'^[0-9]+$') THEN emp
ELSE NULL
END AS emp_no
FROM
DB.table_a;
As Lukasz mentions you should use the TRY_TO_x functions (TRY_TO_NUMERIC, TRY_TO_DOUBLE) as these safely handle parsing the types, and return NULL if the parse fails. The extra note I will add is that both NUMBER/NUMERICs and DOUBLEs will parse 0.1234 but get different results, which you didn't mention as caring about, but I think is worth noting, so I am adding an extra answer to point the difference out.
The CTE is just to get the values into the SQL:
WITH data(emp) as (
select * from values
('ABCD'),
(NULL),
(''),
('0.123'),
('23')
)
SELECT emp
,try_to_numeric(emp) as emp_as_num
,try_to_double(emp) as emp_as_float
FROM data
EMP
EMP_AS_NUM
EMP_AS_FLOAT
'ABCD'
null
null
null
null
null
''
null
null
'0.123'
0
0.123
'23'
23
23
You can test for amp being string and set the string to NULL. Only numeric values will go into the second case statement.
SELECT
CASE
WHEN IS_VARCHAR(emp) then NULL else
case WHEN UPPER(emp) <> LOWER(emp) THEN NULL ELSE emp end
end AS emp_no

replace 'null' strings with NULL in sql

I wanted to check my column. If there was a 'null' string, I wanted to replace it with a NULL value. This works but is there a better way to do it? Such that I don't have to repeat the same thing twice JSON_DATA :"ContactPerson"::STRING
SELECT
IFF(JSON_DATA :"ContactPerson"::STRING = 'null',NULL, JSON_DATA :"ContactPerson"::STRING) AS "ContactPerson",
FROM TEST_TABLE
I want to use REPLACE or REGEX_REPLACE instead.
Using IS_NULL_VALUE could be a bit shorter:
SELECT
IFF(IS_NULL_VALUE(JSON_DATA:"ContactPerson"), NULL,
JSON_DATA :"ContactPerson"::STRING)
FROM TEST_TABLE;
or NULLIF:
Returns NULL if expr1 is equal to expr2, otherwise returns expr1.
SELECT NULIF(JSON_DATA :"ContactPerson"::STRING, 'null')
FROM TEST_TABLE;
Regarding comments:
Still, how would regex_replace be used? REGEXP_REPLACE( , [ , , , , ] )what would the subject be here?
REGEXP_REPLACE(JSON_DATA :"Business_Type"::STRING, 'null', NULL) AS "BS2",but this would give me NULL if "null" doesn't exist in the original value
CREATE FUNCTION:
CALLED ON NULL INPUT
Specifies the behavior of the UDF when called with null inputs. In contrast to system-defined functions, which always return null when any input is null, UDFs can handle null inputs, returning non-null values even when an input is null
and REPLACE function has this behaviour described explicitly"
If any of the arguments is a NULL, the result is also a NULL.

Handling null for char(1) and varcar(2) in hive

I am reading a flat file in hive and i have null values coming in file like below
a|b|null|null|d
and when I create table on top of this with below datatypes
a char(1),b char(1),c char(1),varchar2(2),char(1)
and the value in table coming like this
a,b,n,nu,d
The oneway I can do this is to make the datatype as varchar2(4) and add check at null.
But is there any other way i can do this.
SerDe treats 'null' strings as normal values, no difference between value 'a' and 'null'.
Try to add 'serialization.null.format'='null' property to your table definition:
ALTER TABLE mytable SET tblproperties('serialization.null.format'='null');
Another approach is to use STRING data type and case statements is select:
select case when col = 'null' then null end as col
...

PostgreSQL - return string when testing integer with case statement

When selecting some data from a table I'd like to use a CASE statement to return "n/a" in the event of a null value.
This is a simplified but representative version of the table I'm looking at:
CREATE TABLE test (
id INTEGER NOT NULL,
paid_cents INTEGER NULL DEFAULT NULL,
PRIMARY KEY (id)
);
INSERT INTO test VALUES (1, 100);
INSERT INTO test VALUES (2, NULL);
INSERT INTO test VALUES (3, 0);
I'd expect to be able to use the following query:
SELECT CASE
WHEN paid_cents IS NULL THEN 'n/a'
ELSE paid_cents / 100
END AS "dollar amount"
FROM test
A fiddle of this behaves exactly as I'd expect. However trying this on my real database (PostgreSQL 9.4) results in an error:
ERROR: invalid input syntax for integer: "n/a"
LINE 2: WHEN paid_cents IS NULL THEN 'n/a'
It seems that Postgres is expecting an integer to be returned when testing an integer (and changing 'n/a' to a number does indeed work). I'm guessing that I'll need to CAST somewhere?
either use NULL:
SELECT CASE
WHEN paid_cents IS NULL THEN NULL
ELSE paid_cents / 100
END AS "dollar amount"
FROM test
or cast both to string:
SELECT CASE
WHEN paid_cents IS NULL THEN 'n/a'
ELSE (paid_cents / 100)::text
END AS "dollar amount"
FROM test
You cannot mix datatypes in the columns. As previous answer suggest you should go to a textual datatype (char/varchar/text etc...)
I would use ANSI-SQL and cast( expression as datatype) instead of :: datatype. Same functionality but would be portable between most database engines.
In this case it would be
cast( (paid_cents/100) as text)
instead of
(paid_cents/100) :: text
Cheers.

sql loader - check for specific field value

I have a field called "FLOATVALUE" in csv/text file. I receive this file from third party, this has below possible values
NULL
{}
Any number
When I insert this value as below
.... [OTHER FIELD CHECKS]
isValid "nvl(:isValid, '')",
FLOATVALUE FLOAT EXTERNAL "nvl(:FLOATVALUE, NULL)"
.... [OTHER FIELD CHECKS]
Its checking whethre ":FLOATVALUES" is null or not. If yes it's inserting NULL into the oracle table, if not it's failing to insert for the values ("{}").
The field I'm loading into oracle table is 'FLOATVALUE FLOAT'. I would like to have something like below in my control file -
if :FLOATVALUE is null insert NULL
elseif :FLOATVALUE is '{}' insert NULL
else inert original value
How can specify a condition like above in control file?
You can use the decode function:
decode(:FLOATVALUE, '{}', NULL, :FLOATVALUE)
That says: if FLOATVALUE is '{}', insert NULL, otherwise insert FLOATVALUE
You can use either decode or case when statement. See the example below
Decode :
decode(Float_value,{},NULL,Float_value);
Case when :
CASE [ FLOAT_VALUE ]
WHEN NULL THEN NULL
WHEN {} THEN NULL
ELSE [FLOAT_VALUE]
END;