Apply IsNull function on a date column (SQL Server) - sql

I am trying to apply the IsNull function to a column of a datatype date.
What am trying to do is, to replace the word NULL with an empty string (actual null value) when retrieving the data
The code am using is;
Select
ISNULL("UPDATE_DT", '')
from
MyTable
I have also tried
Select
ISNULL("UPDATE_DT", 0)
from
MyTable
The error am getting is
Msg 103010, Level 16, State 1, Line 1
Parse error at line: 4, column: 1: Incorrect syntax near 'from'.

If you want to see the column as an empty string rather than "NULL", you need to convert the output to a string. To control the format, use convert():
select coalesce(convert(varchar(10), update_dt, 121), '')
. . .
Then use coalesce() (or if you must, isnull()) to replace the NULL value with another string.

Related

How to convert from nchar to decimal in SQL?

I have 2 tables(source and destination) which are respectively NOR_LABOR and ALL_LABOR_DETAILS. In the source table(NOR_LABOR) there is a column "feet_produced" with the data type "nchar(10)". In the destination table(ALL_LABOR_DETAILS) there's a column "labor_feet_produced" with the data type "decimal(18,4)". I want to convert the "feet_produced" from nchar(10) to decimal(18,4) and paste it in the "ALL_LABOR_DETAILS" table's "labor_feet_produced" column.
I have found a code regarding a simillar issue but did not do the exact as I need to do, following is that code snippet :
Select feet_produced AS feet_produced_s, CASE WHEN Isnumeric(feet_produced) = 1
THEN CONVERT(DECIMAL(18,2),feet_produced)
ELSE 0 END AS feet_produced
INTO [MES_DEV].[dbo].[ALL_LABOR_DETAILS]
from [dbo].[NOR_LABOR]
Thank you!
There are values that will test true for IS_NUMERIC, but will fail to convert to decimal.
Instead, use TRY_CONVERT which will return either the successfully-converted-to-decimal value, or a NULL when it fails. (You can then COALESCE to zero to get your desired result).
Here is a short example set of values, using TRY_CONVERT:
SELECT
TryConvert = COALESCE(TRY_CONVERT(decimal(18,4),TestValues),0)
FROM (
VALUES('10.6'),
('ten'),
('7d2'),
('10000000000'),
('10.00000001')
) AS x(TestValues);
The same set of values using your example code will throw an error:
SELECT
IsNumericCase = CASE
WHEN Isnumeric(TestValues) = 1
THEN CONVERT(DECIMAL(18,2),TestValues)
ELSE 0
END
FROM (
VALUES('10.6'),
('ten'),
('7d2'),
('10000000000'),
('10.00000001')
) AS x(TestValues);
This error is returned because 7d2 is numeric, but cannot be converted to decimal.
Msg 8114, Level 16, State 5, Line 14
Error converting data type varchar to numeric.
Im not sure what the issue is with the code that dose not work for you.
But here is how I would do it with a small change in the statement that you just post it.
insert into[MES_DEV].[dbo].[ALL_LABOR_DETAILS](labor_feet_produced)
select CONVERT(DECIMAL(18, 4), feet_produced) AS feet_produced_s from[dbo].[NOR_LABOR]

SQL - Grabbing only a portion of the message in a each row

I have a column name "value" in table T with a long description of errors, it has here is an example of few
but it is also grabbing other rows which i don't need.
Please help?
This answers the original version of the question.
To filter the rows, use regexp_like(). I would suggest:
select t.*
from t
where regexp_like(value, '^An image has error at (1203|12345):')
I am guessing that the final colon is important for the matching.
Why can't you use the LIKE operator?
SELECT t.id, t.value, SUBSTR(t.value, 1, INSTR(t.value, ':')) short_value
FROM t
WHERE value LIKE 'An image has error at 1203:%'
OR value LIKE 'An image has error at 12345:%';
Perhaps your best option seems is a combination of a standard substr+instr to extract the desired value with a regexp_like to determine overall string t desirability overall string.
select substr(value, 1, instr(value, ':')-1 ) value
from d
where regexp_like (value,'An image has error at \d+:');
Although depending the exact requirement for leading test requirement and following numeric value perhaps just
select substr(value, 1, instr(value, ':')-1 ) value
from d
where instr(value, ':') > 1;
Finally you can stay with regexp_substr if you wish. However, Oracle's syntax for that is totally counter intuitive to use of regular expressions:
select value
from (select regexp_substr(value, '(.*):', 1, 1, 'i', 1) value
from d
)
where value is not null;
Demo

How to combine If statement with Substring command in SQL?

I have two types of entries in one column. One type starts with V2, the other starts with a digit. How do I write a query in SQL where I can extract different part of the string based on how it starts?
TextStringColumn
V2|T:GSK|1000000|S1:TES|S2:N/A|Q:24|S:0.5gx3|PD:2020-10-22|C:QQ
2000308|S1:BES|T:SKY|Q:16446G|BSI:BPKGVAXQOHZFWGE
I wrote
SELECT TextStringColumn, If(TextStringColumn like 'V2%',SUBSTRING(TextStringColumn ,10,7),SUBSTRING(TextStringColumn ,1,7)) As NumberCol
FROM TestTable
But I keep getting syntax errors.
Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'If'.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.
The desired result will be
TextStringColumn NumberCol
V2|T:GSK|1000000|S1:TES|S2:N/A|Q:24|S:0.5gx3|PD:2020-10-22|C:QQ 1000000
2000308|S1:BES|T:SKY|Q:16446G|BSI:BPKGVAXQOHZFWGE 2000308
You may use a CASE expression:
SELECT
CASE WHEN TextStringColumn LIKE 'V2%'
THEN SUBSTRING(TextStringColumn, 10, 7)
ELSE SUBSTRING(TextStringColumn, 1, 7) END AS NumberCol
FROM TestTable;
The above logic assumes the only two varieties of strings are those which start with V2, and those which do not start with V2.
If the strings are variable length ... consider a little JSON
Example
Declare #YourTable Table ([TextStringColumn] varchar(100)) Insert Into #YourTable Values
('V2|T:GSK|1000000|S1:TES|S2:N/A|Q:24|S:0.5gx3|PD:2020-10-22|C:QQ')
,('2000308|S1:BES|T:SKY|Q:16446G|BSI:BPKGVAXQOHZFWGE')
Select A.*
,Val = case when [TextStringColumn] like 'V2%'
then JSON_VALUE(S,'$[2]')
else JSON_VALUE(S,'$[0]') end
From #YourTable A
Cross Apply ( values ( '["'+replace([TextStringColumn],'|','","')+'"]' ) ) B(S)
Returns
TextStringColumn Val
V2|T:GSK|1000000|S1:TES|S2:N/A|Q:24|S:0.5gx3|PD:2020-10-22|C:QQ 1000000
2000308|S1:BES|T:SKY|Q:16446G|BSI:BPKGVAXQOHZFWGE 2000308

how to convert the output of sub query into numeric

select rptName
from RptTable
where rpt_id in (
select LEFT(Reports, NULLIF(LEN(Reports)-1,-1))
from repoAccess1
where uid = 'VIKRAM'
)
this is my sql query In which i have use the sub query to access selected field
in this sub query returns
select LEFT(Reports, NULLIF(LEN(Reports)-1,-1))
from repoAccess1
where uid = 'VIKRAM'
Returns
1,2
that means the query should be like
select rptName
from RptTable where rpt_id in (1,2)
But i m getting this error
Msg 8114, Level 16, State 5, Line 1
Error converting data type nvarchar to numeric.
could anyone tell me ow to modify to get exact ans
It's a little hard to tell without the concrete table definitions, but I'm pretty sure you're trying to compare different data types to each other. If this is the case you can make use of the CAST or the CONVERT function, for example:
SELECT
[rptName]
FROM [RptTable]
WHERE [rpt_id] IN
(
SELECT
CONVERT(int, LEFT([Reports], NULLIF(LEN([Reports]) - 1, -1)))
FROM [repoAccess1]
WHERE [uid] = 'VIKRAM'
)
UPDATE: Since you have updated your question: The LEFT function returns results of either varchar or nvarchar data type. So the resulting query would be
SELECT
[rptName]
FROM [RptTable]
WHERE [rpt_id] IN('1', '2')
Please note the apostrophes (is this the correct term?) around the values. Since [rpt_id] seems to be of data type int the values cannot implicitly be converted. And that's where the aforementioned CAST or CONVERT come into play.
If I understand correctly, the subquery is returning a single row with a value of '1,2'. This is not a number, hence the error.
Before continuing, let me emphasize that storing values in comma delimited string is not the SQL-way of doing things. You should have one row per id, with proper types and foreign keys defined.
That said, sometimes we are stuck with other people's really bad design decisions. If this is the case, you can use LIKE:
select rptName
from RptTable r
where exists (select 1
from repoAccess1 a
where a.uid = 'VIKRAM' and
',' + a.reports + ',' like '%,' + cast(r.rpt_id as varchar(255)) + ',%'
);
select rptName
from RptTable
where rpt_id in (
select CAST(LEFT(Reports, NULLIF(LEN(Reports)-1,-1)) AS INT) as Val
from repoAccess1
where uid = 'VIKRAM'
)
Your query would work fine when (LEFT(Reports, NULLIF(LEN(Reports)-1,-1)) ) returns either 1 or 2 since SQL Server implicitly converts the varchar value to numeric.
It seems there might be a data issue. One of the data returned by LEFT function is non-numeric. In order to find that particular record you can use isnumeric function. Try like this,
SELECT rptName
FROM RptTable
WHERE rpt_id IN (
SELECT LEFT(Reports, NULLIF(LEN(Reports) - 1, - 1))
FROM repoAccess1
WHERE uid = 'VIKRAM'
AND ISNUMERIC(LEFT(Reports, NULLIF(LEN(Reports) - 1, - 1))) = 1
)

Removing leading zeros from varchar sql developer

How would I remove the leading zeros from a number which is in the form of varchar.
I have tried the following:
Option 1:
insert into example_table (columnName)
(SELECT
SUBSTR(columnName2, InStr('%[^0 ]%', columnName2 + ' '), 10)
from columnName2);
With this, the error I get is
SQL Error: ORA-01722: invalid number
ORA-02063: preceding line from xxxx
01722. 00000 - "invalid number"
Option 2:
insert into example_table (columnName)
(SELECT
SUBSTR(columnName2, InStr('%[^0 ]%', columnName2 + ' '),
LEN(columnName2))
from columnName2);
This time I get
Error at Command Line:23 Column:87
Error report:
SQL Error: ORA-00904: "LEN": invalid identifier
Option 3:
SUBSTRING
(columnName2, PATINDEX('%[^0 ]%', columnName2 + ' '), 10));
Similar to above, I get
Error at Command Line:23 Column:41
Error report:
SQL Error: ORA-00904: "PATINDEX": invalid identifier
00904. 00000 - "%s: invalid identifier"
EDIT
I think that the trim route might be my best option, however... I am uncertain how to use it in the case I have.
INSERT INTO temp_table
(columnNeedTrim, column2, column3, column4, column5)
SELECT * FROM
(SELECT(
SELECT TRIM(leading '0' from columnNeedTrim) FROM table),
table.column2,
table2.column3,
table.column4
table.column5
FROM
table
INNER JOIN
table2 ON
table1.columnNeedTrim=table2.columnNeedTrim)
WHERE NOT EXISTS (SELECT * FROM temp_table);
I now get an error because my trim function returns multiple row result.
Error report:
SQL Error: ORA-01427: single-row subquery returns more than one row
01427. 00000 - "single-row subquery returns more than one row"
I am not sure how to work a trim (or a cast) into the statement above. Any help on that?
Thanks for any help!
Oracle has built-in TRIM functions for strings. Assuming you have a string like '00012345' and you want to keep it as a string, not convert it to an actual NUMBER, you can use the LTRIM function with the optional second setparameter specifying that you're triming zeros:
select ltrim('000012345', '0') from dual;
LTRIM
-----
12345
If you might also have leading spaces you can trim both in one go:
select ltrim(' 00012345', '0 ') from dual;
LTRIM
-----
12345
You could also convert to a number and back, but that seems like a lot of work unless you have other formatting that you want to strip out:
select to_char(to_number('000012345')) from dual;
Incidentally, the immediate reason you get the ORA-01722 from your first attempt is that you're using the numeric + operator instead of Oracle's string concentenation operator ||. It's doing an implicit conversion of your string to a number, which it seems you're trying to avoid, and the implicit conversion of the single space - whatever that is for - is causing the error. (Possibly some of your values are not, in fact, numbers at all - another example of why numbers should be stored in NUMBER fields; and if that is the case then converting (or casting) to a number and back would still get the ORA-01722). You'd get the same thing in the second attempt if you were using LENGTH instead of LEN. Neither would work anyway as INSTR doesn't recognise regular expressions. You could use REGEXP_INSTR instead, but you'd be better off with #schurik's REGEXP_REPLACE version if you wanted to go down that route.
I'm not sure I understand your question edit. It looks like your insert can be simplified to:
INSERT INTO temp_table (columnNeedTrim, column2, column3, column4, column5)
SELECT LTRIM(table1.columnNeedTrim, '0 '),
table1.column2,
table1.column3,
table1.column4,
table1.column5
FROM table1
INNER JOIN table2 ON table2.columnNeedTrim = table1.columnNeedTrim
WHERE NOT EXISTS (
SELECT * FROM temp_table
WHERE columnNeedTrim = LTRIM(t42.columnNeedTrim, '0 '));
(I don't understand why you're doing a subquery in your version, or why you're getting the trimmed value from another subquery.)
You could also use MERGE:
MERGE INTO temp_table tt
USING (
SELECT LTRIM(t42.columnNeedTrim, '0 ') AS columnNeedTrim,
t42.column2,
t42.column3,
t42.column4,
t42.column5
FROM t42
INNER JOIN t43 ON t43.columnNeedTrim=t42.columnNeedTrim
) sr
ON (sr.columnNeedTrim = tt.columnNeedTrim)
WHEN NOT MATCHED THEN
INSERT (tt.columnNeedTrim, tt.column2, tt.column3, tt.column4, tt.column5)
VALUES (sr.columnNeedTrim, sr.column2, sr.column3, sr.column4, sr.column5);
SELECT '00012345' AS zeroWith, TRIM(LEADING 0 FROM '00012345') AS zeroWithOut
FROM dual;
Result : zeroWith > 00012345 & zeroWithOut > 12345
For SQL server, if you know the data is actually a number, you can just cast it twice. Casting to an int removes the leading zeroes, then back to a string for insertion. I'm assuming you can do something similar in Oracle.
DECLARE #vc varchar(100) = '0000000000000000000001234'
SELECT CAST(CAST(#vc as int) as varchar(100))
Returns:
1234
You do not have to replace it. It will be handled by Oracle.
SELECT TO_NUMBER(num)
FROM
(
SELECT '00000123' AS num FROM DUAL
);
-- Result:
-- 123
You can use the following methods:
Option 1: use the ltrim function as Alex said:
select ltrim('0005400', '0')
from dual;
Option 2: use the trim function:
select trim(leading '0' from '0005400')
from dual;
Oracle trim function has the leading, trailing and both options.
Option 3: use regular expressions:
select regexp_substr('0005400', '[^0].+')
from dual;