I use the following SQL to concatenate several database columns from one table into one column in the result set:
SELECT (field1 + '' + field2 + '' + field3) FROM table1
When one of the fields is null I got null result for the whole concatenation expression. How can I overcome this?
The database is MS SQL Server 2008. By the way, is this the best way to concatenate database columns? Is there any standard SQL doing this?
The SQL standard way of doing this would be:
SELECT COALESCE(field1, '') || COALESCE(field2, '') || COALESCE(field3, '') FROM table1
Example:
INSERT INTO table1 VALUES ('hello', null, 'world');
SELECT COALESCE(field1, '') || COALESCE(field2, '') || COALESCE(field3, '') FROM table1;
helloworld
If you were using SQL 2012 or above you could use the CONCAT function:
SELECT CONCAT(field1, field2, field3) FROM table1
NULL fields won't break your concatenation.
#bummi - Thanks for the comment - edited my answer to correspond to it.
Normal behaviour with NULL is that any operation including a NULL yields a NULL...
- 9 * NULL = NULL
- NULL + '' = NULL
- etc
To overcome this use ISNULL or COALESCE to replace any instances of NULL with something else..
SELECT (ISNULL(field1,'') + '' + ISNULL(field2,'') + '' + ISNULL(field3,'')) FROM table1
If you are having a problem with NULL values, use the COALESCE function to replace the NULL with the value of your choice. Your query would then look like this:
SELECT (COALESCE(field1, '') + '' + COALESCE(field2, '') + '' + COALESCE(field3,'')) FROM table1
http://www.codeproject.com/KB/database/DataCrunching.aspx
Use ISNULL to overcome it.
Example:
SELECT (ISNULL(field1, '') + '' + ISNULL(field2, '')+ '' + ISNULL(field3, '')) FROM table1
This will then replace your NULL content with an empty string which will preserve the concatentation operation from evaluating as an overall NULL result.
If both Column are numeric Then Use This code
Just Cast Column As Varchar(Size)
Example:
Select (Cast(Col1 as Varchar(20)) + '-' + Cast(Col2 as Varchar(20))) As Col3 from Table
Just Cast Column As Varchar(Size)
If both Column are numeric then use code below.
Example:
Select (Cast(Col1 as Varchar(20)) + '-' + Cast(Col2 as Varchar(20))) As Col3 from Table
What will be the size of col3 it will be 40 or something else
Related
Is there any alternate way to concatenate SQL columns with comma separated. I am using below logic for concatenation. The columns (col1,col2,col3) can have null values.
select
stuff(
left(concat(col1,',',col2,',',col3),
len(concat(col1,',',col2,',',col3)) -
patindex('%[^,]%',reverse(concat(col1,',',col2,',',col3)))+1
)
,1,
patindex('%[^,]%',concat(col1,',',col2,',',col3))-1,''
)
from mytable
Sample data/output
In more recent versions of SQL Server you can use concat_ws():
select concat_ws(',', col1, col2, col3)
In earlier versions, there are various approach. A pretty simple one is:
select stuff( concat(',' + col1, ',' + col2, ',' + col3), 1, 1, '')
You can concat separators conditionally. This will output an empty string if either of the columns are null or empty.
select concat(col1,
case when len(col2)>1 then ',' else '' end,
col2,
case when len(col3)>1 then ',' else '' end,
col3)
from your_table;
To output null if either of the columns are null or empty, wrap the concat inside a nullif like this
select nullif(concat(col1,
case when len(col2)>1 then ',' else '' end,
col2,
case when len(col3)>1 then ',' else '' end,
col3),'')
from your_table;
I have columns
Col1|Col2|Col3
Aaaa|Bbbb|Cccc
Null|Bbbb|Cccc
Aaaa|Bbbb|Null
My result should look like
Aaaa,Bbbb,Cccc
Bbbb,Cccc
Aaaa,Bbbb
I tried this with the common '+' way of concatenation like
Select Col1 + ', ' + Col2 + ', ' + Col3
but with this statement I do get Nulls in the resultset if there is a Null in one of the columns. I could do something like
ISNULL(Col1, ' ')
but this end up in having ',' signs messing around
Can anyone help me out here?
The CONCAT() function solves your problem:
Select CONCAT(Col1, ', ', Col2, ', ', Col3)
It ignores NULL values.
The most recent versions of SQL Server support CONCAT_WS():
CONCAT_WS(', ', col1, col2, col3)
This produces slightly different results. For instance, if the second two values are NULL, the first returns 'A,,' but the second returns 'A'. I'm not sure which you really want.
I am working in SQL and I have 3 columns Current Name, Given Full Name and Whether the names match (Y or No)
The problem with that is that when I am comparing the strings in the first 2 columns, it is not showing me the current result. For example, I am not finding a way to prove that 'Tushar Sharma' is same as 'Tushar-Sharma' considering that Tushar Sharma is the current full name and Tushar-Sharma is the name that has been extracted from a report.
I am stuck at the LIKE statement as to what to do if I want to have hyphen(-) included in the comparison so that I get a Y in the 3rd column.
Thank you
One option is to remove the hyphen for the comparison:
select (case when replace(given_name, '-', '') = replace(full_name, '-', '') then 'Y' else 'N' end) as names_match
You can use replace() with like as well:
select (case when replace(given_name, '-', '') like '%' + replace(full_name, '-', '') '%' then 'Y' else 'N' end) as names_match
Replace - with whitespace and compare, you can also use regex or fuzzy matching to improve the match for other conditions.
AND REPLACE(CurrentName, '-', ' ') = REPLACE(GivenName, '-', ' ');
Ex:
AND REPLACE('Tushar Sharma', '-', ' ') = REPLACE('Tushar-Sharma', '-', ' ')
will eval to
AND 'Tushar Sharma' = 'Tushar Sharma'
this will work:
select currentname,givenfullname,case when regexp_replace(currentname,' ','') like
regexp_replace(givenfullname,' ','') the 'Y' else 'N' end as matchstatus from
table_name;
So I am extracting data from one table to another
SELECT *
LTRIM(ADRESSE + ',' + ADRESSE2) AS ADDRESS12
FROM [Homestore].[dbo].[CLIENT]
Issue is that if the cells are blank i still get a comma ,
I have tried using & instead of + but nvarchar is incompatible in the '&' operator. Any ideas how I only insert the comma if there is something to concatenate?
You want the equivalent of CONCAT_WS() in other databases. You can do this with STUFF() and some string logic in SQL Server:
SELECT c.*
STUFF( (COALESCE(',' + ADRESSE, '') +
COALESCE(',' + ADRESSE2, '') +
), 1, 1, ''
) AS ADDRESS12
FROM [Homestore].[dbo].[CLIENT] c;
This structure is convenient, because you can just add more COALESCE() expressions for more columns.
use case expression
SELECT *, LTRIM(ADRESSE + case when ADRESSE is not null then ',' end + ADRESSE2) AS ADDRESS12
FROM [Homestore].[dbo].[CLIENT]
use case when for null checking
SELECT *
LTRIM(ADRESSE + case when ADRESSE2 is not null then
',' else '' end + ADRESSE2) AS ADDRESS12
FROM [Homestore].[dbo].[CLIENT]
I have a table that has 3 phone number fields (among other fields).
DayTimePhone
EveningPhone
MobilePhone
I need to pull up records where there is a number in at least one of them.
SELECT Field1
,Field2
,Field3
,DayTimePhone
,EveningPhone
,MobilePhone
FROM Contact
WHERE DayTimePhone IS NOT NULL
AND EveningPhone IS NOT NULL
AND MobilePhone IS NOT NULL
But in some results I get rows where all three fields are blank. They don't have a NULL, just blank. So my code works to an extent.
I tried:
SELECT Field1, Field2, Field3
,CASE isnull (DayTimePhone, '-') WHEN '' THEN '-' WHEN ' ' THEN'-'
END DayTimePhone
,CASE isnull (EveningPhone, '-') WHEN '' THEN '-' WHEN ' ' THEN'-'
END EveningPhone
,CASE isnull (MobilePhone, '-') WHEN '' THEN '-' WHEN ' ' THEN'-'
END MobilePhone
INTO #TempTable
--------------------------------
SELECT * FROM #TempTable
WHERE DayTimePhone IS NOT NULL
AND EveningPhone IS NOT NULL
AND MobilePhone IS NOT NULL
AND DayTimePhone != '-'
AND EveningPhone != '-'
AND MobilePhone != '-'
But this code only gives me results WHERE there is a NULL or - in the fields.
How do I get results where there is at least 1 number in any of the three fields?
Edit
Please see my comment to #LONG answer. That solution worked but now the results are also showing rows where the DayTimePhone reads 0. Please read my comment below.
Another option is to simply check the length of the string representing the number. If it is null or too short then simply exclude it from the result.
SELECT * FROM #TempTable
WHERE (
(ISNULL(LEN(RTRIM([DayTimePhone])), 0) > 8)
OR
(ISNULL(LEN(RTRIM([EveningPhone])), 0) > 8)
OR
(ISNULL(LEN(RTRIM([MobilePhone])), 0) > 8)
)
Try:
SELECT * FROM #TempTable
WHERE (DayTimePhone IS NOT NULL AND REPLACE(DayTimePhone,' ','') != '')
OR (EveningPhone IS NOT NULL AND REPLACE(EveningPhone ,' ','') != '')
OR (MobilePhone IS NOT NULL AND REPLACE(MobilePhone ,' ','') != '')
Having blank is not always a good table design, try to update them with NULL
UPDATE:
From you comments, could you please indicate which type 0 phone that is?
If you still see '0' in the result, that means that is definitely not a single 0.
You can just go with WHERE DayTimePhone != '0-0-0' or DayTimePhone != '0-0', but this is not a skeleton key. If you are checking with U.S phone numbers, you can go with Validate U.S. Phone number and using LIKE, '[0-9]', expression pattern like this to check. I will try to give you a general way to check a validate U.S phone query.
A pretty simple way is:
SELECT tt.*
FROM #TempTable tt
WHERE tt.DayTimePhone <> '-' OR
tt.EveningPhone <> '-' OR
tt.MobilePhone <> '-';
NULL values will not return true for the <> comparison.
You should first clean you table from nulls and blank values.
That was actually done already. What you need now is to use the OR command instead of AND and check it for the value you replaced ('-'):
SELECT * FROM #TempTable
WHERE (DayTimePhone IS NOT NULL != '-')
OR (EveningPhone IS NOT NULL != '-')
OR (MobilePhone IS NOT NULL != '-')
I hope it helps...