Concatenate with NULL values in SQL - 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

Related

DB2 SQL Split Record by Delimiter if exists

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

SQL Server CASE statement with multiple THEN clauses

I have seen several similar questions but none cover what I need. I need to put another THEN statement after the first one. My column contains int's. When it returns NULL I need it to display a blank space, but when I try the below code, I just get '0'.
CASE
WHEN Column1 IS NULL
THEN ''
ELSE Column1
END
If I try to put a sting after THEN then it tells me that it cannot convert it from int. I need to convert it to varchar and then change its output to a blank space afterwards, such as:
e.g.
CASE
WHEN Column1 IS NULL
THEN CONVERT(varchar(10), Column1)
THEN ''
ELSE Column1
END
Is there a way of doing this?
Thanks
Rob
A case expression returns a single value -- with a given type. If you want a string result, then you need to be sure that all paths in the case return strings:
CASE WHEN Column1 IS NULL
THEN ''
ELSE CAST(Column1 AS VARCHAR(255))
END
This is more simply written using COALESCE():
COALESCE(CAST(Column1 as VARCHAR(255)), '')
You cannot display an integer as a "blank" (other than using a NULL value).

PostgreSQL concatting multiple cases gives null as result

I'm pretty new to PostgreSQL. The next query works in Oracle but won't work in PSQL:
select case 1 when null then null else 1||' ' end ||
case 2 when null then null else 2||' ' end ||
case 3 when null then null else 3 end as total
from numbers
If 1 and 2 are not null but only 3 is null, the result of total will be null despite the fact that 1 en 2 are not null and the result of total should not be null.
The end result should be that when one of 3 columns is not null, total should not be null. Is that possible?
For Postgres - unlike Oracle - an empty string '' and null are two different things. In Oracle a string concatenation with null treats the null value as an empty string. However when you store an empty string ('') in Oracle it treats it as a null value.
In SQL, all (or nearly all) operators are defined such that if any argument is null the result is also null, e.g. 42 + null or 'foo'||null.
Also case 1 when null makes no sense. 1 is never null and thus the when part would never be executed. Additionally you can't test for null that way. You need to use is null but then you can't use the abbreviated case syntax.
You probably meant to write something like this:
select case when first_column is null then '' else first_column||' ' end ||
case when second_column is null then '' else second_column||' ' end ||
case when third_column is null null then '' else third_column end as total
from numbers
However you can make this a lot easier using coalesce():
select coalesce(first_column, '')||' '||coalesce(second_column, '')||' '||coalesce(third_column, '')
or use concat() which treats null as an empty string:
select concat(first_column, ' ', second_column, ' ', third_column)
or even simpler use concat_ws() "concat with separator":
select concat_ws(' ', first_column, second_column, third_column)
concat_ws() will put the separator (the first parameter) between every value of the other parameters, but treats null values and empty strings properly, so that the separator does not occur twice between two values.
concat('one', ' ', null, ' ', '') returns 'one '
but concat_ws(' ', 'one', null, '') will return 'one'

Oracle null check for string field

In this below example why other than "NAME1" all giving null as result in oracle 11g.
If I mention space explicitly it takes space otherwise null only not empty string.Please help me to clarify this.
In NAME2 I specify the empty space but still it gives null.
select
NVL(NAME,' ') AS NAME1,
NVL(NAME,'') AS NAME2,
NVL(NAME,NULL) AS NAME3,
NAME AS NAME4
from employee
OUTPUT :
(space),null,null,null
Because in Oracle a ZERO length varchar is treated as NULL.
In your example
NVL(NAME, ' ') AS NAME1 will evaluate to either NAME or ' ' - empty string.
NVL(NAME, '') as NAME2 will evaluate to either NAME or a zero length string
Because '' is equal with null in oracle. For example these two queries are same:
update test set name='' where id = 15
update test set name=null where id = 15
The reason is that in Oracle an empty string is equivalent to NULL.
You can see that this is true by executing the followig query
SELECT 'x' FROM DUAL WHERE '' IS NULL
This should return a single row, meaning that the condition '' IS NULL is true.

CONCAT'ing NULL fields

I have a table with three fields, FirstName, LastName and Email.
Here's some dummy data:
FirstName | LastName | Email
Adam West adam#west.com
Joe Schmoe NULL
Now, if I do:
SELECT CONCAT(FirstName, LastName, Email) as Vitals FROM MEMBERS
Vitals for Joe is null, as there is a single null field. How do you overcome this behaviour? Also, is this the default behaviour in MS SQL Server?
Try
ISNULL(FirstName, '<BlankValue>') -- In SQL Server
IFNULL(Firstname, '<BlankValue>') -- In MySQL
So,
CONCAT(ISNULL(FirstName,''),ISNULL(LastName,''),ISNULL(Email,'')) -- In SQL Server
CONCAT(IFNULL(FirstName,''),IFNULL(LastName,''),IFNULL(Email,'')) -- In MySQL
would return the same thing without the null issue (and a blank string where nulls should be).
Look at CONCAT_WS
For example:
CONCAT_WS('',NULL,"TEST STRING","TEST STRING 2")
Yields
TEST STRINGTEST STRING 2
This is easier than constructing IFNULL around everything. You can use an empty string as the separator.
In mysql isnull wont work some time. try IFNULL(),
CONCAT(IFNULL(FirstName,''),IFNULL(LastName,''),IFNULL(Email,''))
SELECT ISNULL(FirstName,'')+ISNULL(LastName,'')+ISNULL(Email,'') as Vitals FROM MEMBERS
is recommended, but if you are really hooked on CONCAT, wrap it in {fn } and you can use the ODBC function like:
SELECT {fn CONCAT(ISNULL(FirstName,''), ISNULL(LastName,''), ISNULL(Email,''))} as Vitals FROM MEMBERS
If you need first<space>last but just last when first is null you can do this:
ISNULL(FirstName+' ','') + ISNULL(LastName,'')
I added the space on firstname which might be null -- that would mean the space would only survive if FirstName had a value.
To put them all together with a space between each:
RTRIM(ISNULL(Firstname+' ','') + ISNULL(LastName+' ','') + ISNULL(Email,''))
You can always use the CONCAT_NULL_YIELDS_NULL setting..
just run SET CONCAT_NULL_YIELDS_NULL OFF and then all null concatenations will result in text and not null..
If you get (like I do in MySQL):
#1582 - Incorrect parameter count in the call to native function 'ISNULL'
You can replace ISNULL function by COALESCE:
CONCAT(COALESCE(FirstName,''),COALESCE(LastName,''),COALESCE(Email,''))
Stefan's answer is correct.
To probe a little bit deeper you need to know that NULL is not the same as Nothing. Null represents the absence of a value, or in other words, not defined. Nothing represents an empty string which IS in fact a value.
Undefined + anything = undefined
Good database tidbit to hold onto!
Starting from MS SQL Server 2012 it was introduced CONCAT function
and according to MSDN
Null values are implicitly converted to an empty string. If all the
arguments are null, an empty string of type varchar(1) is returned.
so it's enough to use CONCAT without IsNull
CONCAT(FirstName, LastName, Email)
SQL Server does not have a CONCAT function.
(Update: Starting from MS SQL Server 2012 it was introduced CONCAT function)
In the default SQL Server behavior, NULLs propagate through an expression.
In SQL Server, one would write:
SELECT FirstName + LastName + Email as Vitals FROM MEMBERS
If you need to handle NULLs:
SELECT ISNULL(FirstName, '') + ISNULL(LastName, '') + ISNULL(Email, '') as Vitals FROM MEMBERS
In the case of MS Access
Option 1) SELECT (FirstName + " " + LastName + " " + Email) as Vitals FROM MEMBERS
You will get blank result in the case of any field with null.
Option 2) SELECT (FirstName & " " & LastName & " " & Email) as Vitals FROM MEMBERS
You will get Space in place of field with null.
After observing the answers for this question, you may combine all of them into one simple solution
CONCAT_WS(',',
IF(NULLIF(FirstName, '') IS NULL, NULL, FirstName),
IF(NULLIF(LastName, '') IS NULL, NULL, usr_lastname),
IF(NULLIF(Email, '') IS NULL, NULL, Email))
So, in short we use CONCAT_WS to concatenate our fields and separate them with ,; and notice that NULL fields nor EMPTY wont concatenated
NULLIF will check if the field is NULL or EMPTY, a field that contains only spaces or is empty as well, ex: '', ' ') and the output will be either NULL or NOT NULL
IF Will out put the field if it's not NULL or EMPTY