DB2 SQL Split Record by Delimiter if exists - sql

I would like to return the portion of a string BEFORE a delimiter (in this case, a hyphen). What I find is that DB2 is throwing an error because there's an inconsistency in the values of the column where some records have a hyphen meanwhile others do not. So, I'd like to return the string before hyphen if it exists, otherwise just return the string as is.
Example shown with COLUMN1 below:
ID
COLUMN1
1
ASHJE-JFE
2
QER-SK
3
KSETK
4
SDJ-EJLF
I wrote the following query to return the string prior/before '-' but, I get the following error:
The statement was not executed because a numeric argument of a scalar
function is out of range.
I believe this is because there are records where a hyphen does not exist...
select distinct column1, locate('-',column1), substr(column1,1, (locate('-',column1) - 1)) from db2.table
where column1 is not null
fetch first 25 rows only
with ur
Does anyone know how to accomplish something similar but return the string as is when a hyphen does not exist? Thank you!

You may use the following expression:
SUBSTR (COLUMN1, 1, COALESCE (NULLIF (LOCATE ('-', COLUMN1), 0) - 1, LENGTH (COLUMN1)))

You can use a CASE statement to search for the hyphen along with a LIKE operator and % wildcards.
SELECT ID, column1,
CASE WHEN column1 LIKE '%-%'
THEN substr(column1,1,locate('-',column1)-1)
ELSE column1
END AS column2
FROM fileName
WHERE column1 IS NOT NULL
FETCH FIRST 25 ROWS ONLY
See Fiddle
Result:
ID
COLUMN1
COLUMN2
1
ASHJE-JFE
ASHJE
2
QER-SK
QER
3
KSETK
KSETK
4
SDJ-EJLF
SDJ

Related

SQL : Split numeric string from as specific position by using commas as indicator

I have two columns in my data. Column1 contains the numeric strings where digits are separated by commas and Column2 contains a number. I want to truncate the column1 by using the column2 as the position identifier for comma starting from right end of the string.
Column1
Column2
Expected_OP
0,12,38,69,96,127,159,187
2
0,12,38,69,96,127
0,0,0,0,0,0,0,0,0,0
3
0,0,0,0,0,0,0
0,0,0,0,0,0
4
0,0
Here's a working one, with a bit of trial-and-error:
select column1, column2, substr(column1,1,instr(column1,',',1,length(column1) - length(replace(column1,',','')) - column2 + 1) - 1) from test
db<>fiddle here
(Used postgresql) (Note, there is no error-checking with regards to invalid input (example no commas or too high number in column2)

How to choose output length based on whether or not first character is a letter?

I am trying to return a column in sql
which should return 4 characters from the column when the character starts with an alphabet, for a numeric it should return only 3 characters .
Eg:
column:
B98497
C68756
r45789
123467
578912
output:
the above column should return the following
column:
B984
C687
r457
123
578
I used the following code but it returns only first three characters
my code:
select substring(column,1,3)
from table
the output for my code:
column
B98
C68
r45
123
578
how do I get an output like this:
B984
C687
r457
123
578
One method is:
select left(col, 3 + (col rlike '^[a-zA-Z'))
This uses the fact that boolean expressions evaluate to 1 or 0 in a number context.
If you already use MySQL 8.0, there's a one-liner:
SELECT REGEXP_SUBSTR(column1, '[a-z]?[0-9]{3}') FROM Table1;
Demo. And here's the corresponding docpage.
If it's 5.7, you have to check the first symbol against letter character class, like this:
SELECT LEFT(column1, IF(column1 RLIKE '^[a-z]', 4, 3)) FROM Table1;
... which can actually be simplified as showed in #GordonLinoff answer.
Demo.
Following Should Do
select
CASE WHEN substring(TheColumn, 1,1) LIKE '[0-9]' THEN substring(TheColumn, 1,3)
ELSE substring(TheColumn, 1, 4) END
from [dbo].[TabAlpNum]

Where x character equal value

How can I select records where in the column Value the 5th character is letter A?
For example the following records:
ID Value
-------------------------
1 1234A5636A6363
2 1234A4343B6363
3 1234B5353A6363
if I run
select * from table
where Value like '%A%'
this will return all records
but all I want is the first 2 where the 5th character is A, regardless if there are more A characters in the text or not
select *
from your_table
where substring(Value, 5, 1) = 'A'
The LIKE operator, in addition to %, which matches any number of any character, can use _, which matches any one single character. You may try:
SELECT *
FROM yourTable
WHERE Value LIKE '____A%'; -- 4 underscores here
use like below by using _(underscore)
LIKE '____A%'
SQL Server
select *
from YourTableName
where CHARINDEX('A', ColumnName) = 5
Note:- This finds where string 'A' starts at position 5
AND specify Your ColumnName

Concatenate with NULL values in SQL

Column1 Column2
------- -------
apple juice
water melon
banana
red berry
I have a table which has two columns. Column1 has a group of words and Column2 also has a group of words. I want to concatenate them with + operator without a space.
For instance: applejuice
The thing is, if there is a null value in the second column, i only want to have the first element as a result.
For instance: banana
Result
------
applejuice
watermelon
banana
redberry
However, when i use column1 + column2, it gives a NULL value if Comunm2 is NULL. I want to have "banana" as the result.
Use the COALESCE function to replace NULL values with an empty string.
SELECT Column1 + COALESCE(Column2, '') AS Result
FROM YourTable
A few posts I have made tagged MSSQL have been renamed to 'SQL' by a moderator. So I am assuming you are using MSSQL
COALESCE will return the FIRST non-null value.
SELECT COALESCE('a', NULL, 'c')
will only return 'a'
If you want Firstname + Lastname, where sometimes one or the other is NULL, use CONCAT. Concat adds the strings together and replaces NULLS with 0 length non-null value.
SELECT CONCAT('a', NULL, 'c')
will return 'ac'
If you want Fn space + middle name space + LN, combine concatinate with CONCAT:
SELECT CONCAT('a' + ' ', NULL + ' ', 'c')
Will return 'a c'.
The space after middlename (null) is eliminated with the + and NULL.
NULL + ' ' is null.
So in cases where Middlename or Firstname is null, you won't get extra unwanted spaces.
Standard SQL requires that string concatenation involving a NULL generates a NULL output, but that is written using the || operation:
SELECT a || b
FROM SomeTable;
The output will be null if either a or b or both contains a NULL.
Using + to concatenate strings indicates that you are using a DBMS-specific extension. The behaviour might be the same as the standard requires - indeed, that seems to be the gist of your question.
Some DBMS - notably Oracle - tend to treat null strings as equivalent to empty strings; then you can concatenate away merrily. However, that behaviour is not strictly standard-compliant if the || operator is used.
Consider using COALESCE or NVL or IFNULL or some similar function to map the NULL to an empty string before concatenating.
If you are using MySq, use ifnull(Column2, '')
I'm not certain what you're using as your database, but I would look for a "coalesce" function for your particular SQL dialect and use that.
The + sign for concatenation in TSQL will by default combine string + null to null as an unknown value.
You can do one of two things, you can change this variable for the session which controlls what Sql should do with Nulls
http://msdn.microsoft.com/en-us/library/ms176056.aspx
Or you can Coalesce each column to an empty string before concatenating.
COALESCE(Column1, '')
http://msdn.microsoft.com/en-us/library/ms190349.aspx
You can do a union:
(SELECT Column1 + Column2 FROM Table1 WHERE Column2 is not NULL)
UNION
(SELECT Column1 FROM Table1 WHERE Column2 is NULL);
You can use a case condition:
case when column_2 is not null
then concatenate
else column_1
end

Oracle NVL problem

I'm trying to pass a null value as something else in my db and it seems to work without a Where clause like so
select NVL(column1, '0') column1 from table1
produces this
0 test1
0 test2
1 test3
But when I add the where clause like so
select NVL(column1, '0') column1 from table1 where column1 <=1
it produces this
1 test3
But now if I add the following to the query it works
select NVL(column1, '0') column1
from table1
where NVL(column1, '0') <=1
But it seems like a long way round to get the value to show correctly with a Where clause
Any ideas what i'm doing wrong?
Thanks in advance
You cannot refer to an alias defined in the SELECT list from the WHERE clause. So if you apply the NVL function in the SELECT list, you'd need the same function call in the WHERE clause (as you've demonstrated) or you would need to apply the function in an inline view
SELECT column1
FROM (SELECT nvl(column1, 0) column1
FROM table1)
WHERE column1 <= 1
Note that for general sanity, if COLUMN1 is a NUMBER, the second parameter to NVL should also be a NUMBER. Otherwise, you're going to do implicit conversions and your comparison operations may end up using string comparison semantics rather than numeric comparison semantics. Since the string '12' is less than the string '2', that can lead to unexpected results.
you have shown the correct way.
an alternative would be to say
OR column IS NULL