Related
I have full name that contains blank or null value and cause an error when I split into first name,lastname.
here is the error:
ERROR [22011] [IBM][DB2/AIX64] The statement was not executed because a numeric argument of a scalar function is out of range.
here is my original code:
UPPER(right(AGENT_NM, (char_length (AGENT_NM) - position( ' ', AGENT_NM))))|| ', ' || UPPER(left(AGENT_NM, position( ' ', AGENT_NM) - 1)) AS AGENT_NAME,
here is what I have tried:
1-
CASE when REGEXP_COUNT(AGENT_NM,',')> 0 then left (AGENT_NM, position( ' ', AGENT_NM) - 1) END AS FNAME,
2-
CASE when(AGENT_NM= ' ') then Null Else left (AGENT_NM, position( '
> ', AGENT_NM) - 1) END AS FNAME,
However it returns blank.
Concatenate a space onto the end of your name first:
SELECT
TRIM(UPPER(RIGHT(AGENT_NMs, char_length (AGENT_NMs) - position( ' ', AGENT_NMs))))||
', ' ||
TRIM(UPPER(left(AGENT_NMs, position( ' ', AGENT_NMs) - 1)))
AS AGENT_NAME
FROM
(
SELECT
a.*,
COALESCE(agent_nm, '')||' ' as agent_nms
FROM
yourtable a
) x
Here we use coalesce to ensure the name is not null, and we then add a space on as something for the position function to find
The top bit is just your code tweaked to refer to the new name agent_nms and add an extra trim command for removing any extraneous spaces. It did look like it had one too many brackets in by the way
name=str(input("your name here"))
split_name=name.split(" ")
I need to concatenate the City, State and Country columns into something like City, State, Country.
This is my code:
Select City + ', ' + State + ', ' + Country as outputText from Places
However, because City and State allow null (or empty) value, what happen is, (for example) if the City is null/empty, my output will look like , Iowa, USA; or say the State is empty, then the output will look like Seattle, , USA
Is there anyway I can format the output and remove "unnecessary" commas?
Edited: Because of the requirements, I should not use any other mean (such as PL/SQL, Store Procedure) etc., so it has to be plain SQL statement
select
isnull(City, '') +
case when isnull(City, '') != '' then ', ' else '' end +
isnull(State, '') +
case when isnull(State, '') != '' then ', ' else '' end +
isnull(Country, '') as outputText
from
Places
Since adding a string with null will result null so if they are null (not empty string) this will give you teh desired result
Select isnull(City + ', ','') + isnull(State + ', ' ,'') + isnull(Country,'') as outputText from Places
Use the COALESCE (Transact-SQL) function.
SELECT COALESCE(City + ', ', '') + COALESCE(State + ', ', '')...
In SQL Server 2012 you can use CONCAT function:
select concat(City,', ',State,', ',Country ) as outputText from Places
Not elegant by any means...
first changes city, state,country to null values if blank
then interprets that value for null and adds a space before a comma
then replaces any space comma space ( , ) with empty set.
Query:
SELECT replace(coalesce(Replace(City,'',Null),' ') + ', ' +
coalesce(Replace(State,'',Null), ' ' + ', ' +
coalesce(replace(Country,''Null),''), ' , ','') as outputText
FROM Places
Assumes no city state or country will contain space comma space.
I posted a similar question a while back and now as I need to update this code, I am back to ask a follow-on question. Previous question is here:
Computed column based on nullable columns
My data (Address1, Address2, City, State, Zip, Country) may have incomplete information. I.e. I can't be guaranteed that anything other than State and Country columns will have data.
I would like to have a computed columns for FullAddress.
Previously, I used COALESCE, which worked great if all fields are filled in. Now, as the data requirements have been relaxed, this is no longer an option (because we end with repeated commas in the FullAddress). Here is what I have been using previously (note, I'm just working with SELECT statements here for ease of use - will convert into a computed columns "alter table add" statement once I have something that works for all cases):
SELECT (((((COALESCE([Address1],'')
+ COALESCE(', '+[Address2],''))
+ COALESCE(', '+[City],''))
+ COALESCE(', '+[State],''))
+ COALESCE(', '+[Zip],''))
+ COALESCE(', '+[Country],'')) AS FullAddress
FROM Locations
Now, I have put together an alternative using CASE, but it still doesn't work for the edge case where Address1 is NULL (the problem is that the FullAddress will have ', ' as the first two characters)
SELECT CASE WHEN [Address1] IS NOT NULL THEN [Address1] ELSE '' END
+ CASE WHEN [Address2] IS NOT NULL THEN ', ' + [Address2] ELSE '' END
+ CASE WHEN [City] IS NOT NULL THEN ', ' + [City] ELSE '' END
+ CASE WHEN [State] IS NOT NULL THEN ', ' + [State] ELSE '' END
+ CASE WHEN [Zip] IS NOT NULL THEN ', ' + [Zip] ELSE '' END
+ CASE WHEN [Country] IS NOT NULL THEN ', ' + [Country] ELSE '' END
AS [FullAddress]
FROM Locations
I'm a little stuck at this point. Any recommendations what to try next?
you can use this pattern:
SELECT
ISNULL(Address1 + ', ', '')
+ ISNULL(Address2 + ', ', '')
+ ISNULL(City + ', ', '')
-- ....
AS FullAddress
The result of concation NULL + ', ' is NULL => Address1 + ', ' will be NULL or valid address => ISNULL(Address1 + ', ', '') will be empty string or valid address.
SELECT STUFF(
COALESCE(', ' + Address1, '') + COALESCE(', ' + Address2, '') + ...
1,
2,
''
) AS FullAddress
FROM Locations
The concatenated string will either be empty or start with , (a comma and a space). STUFF() will remove the first two characters and return the rest of the string.
I'm trying not to reinvent the wheel here...I have these four fields:
[tbl_Contacts].[FirstName],
[tbl_Contacts].[MiddleInitial],
[tbl_Contacts].[LastName],
[tbl_Contacts].[Suffix]
And I want to create a FullName field in a view, but I can't have extra spaces if fields are blank...
So I can't do FirstName + ' ' + MiddleInitial + ' ' + LastName + ' ' + Suffix... Because if there is no middle initial or suffix I'd have 2 extra spaces in the field. I think I need a Case statement, but I thought someone would have a handy method for this...Also, the middleinitial and suffix may be null.
Assuming that all columns could be nullable, you can do something like:
RTrim(Coalesce(FirstName + ' ','')
+ Coalesce(MiddleInitial + ' ', '')
+ Coalesce(LastName + ' ', '')
+ Coalesce(Suffix, ''))
This relies on the fact that adding to a NULL value yields a NULL.
Whichever options you choose, here's something to think about: this will be a rather involved and thus time consuming option, especially if you have it in a view which gets evaluated each and every time for each and every row in question.
If you need this frequently, I would recommend you add this to your base table as a persisted, computed field - something like:
ALTER TABLE dbo.tbl_Contacts
ADD FullName AS (insert the statement of your choice here) PERSISTED
When it's persisted, it becomes part of the underlying table, and it's stored and kept up to date by SQL Server. When you query it, you get back the current value without incurring the cost of having to concatenate together the fields and determine which to use and which to ignore...
Just something to think about - something that too many DBA's and database devs tend to ignore and/or not know about....
You may want to pass the FirstName + ' ' + MiddleInitial + ' ' + LastName + ' ' + Suffix concatenation through the REPLACE() function in order to substitute duplicate spaces into a single space.
REPLACE(FirstName + ' ' + MiddleInitial + ' ' + LastName + ' ' + Suffix, ' ', ' ')
-- -- -
EDIT:
Just noticed that some of your fields may be NULL, and therefore the above would not work in that case, as the whole string would become NULL. In this case, you can use the COALESCE() method as suggested by Thomas, but still wrapped it in a REPLACE():
REPLACE(RTRIM(COALESCE(FirstName + ' ', '') +
COALESCE(MiddleInitial + ' ', '') +
COALESCE(LastName + ' ', '') +
COALESCE(Suffix, '')), ' ', ' ')
Test:
SELECT REPLACE(RTRIM(COALESCE('John' + ' ', '') +
COALESCE('' + ' ', '') +
COALESCE('Doe' + ' ', '') +
COALESCE(NULL, '')), ' ', ' ')
-- Returns: John Doe
I had to join Firstname, Middlename, and Lastname. my challenge was to handle NULL values, used following code.
RTRIM(LTRIM(RTRIM(isnull(#firstname,'') + ' ' + isnull(#middlename,'')) + ' ' + isnull(#lastname,'')))
Test different scenarios if you are interested :)
DECLARE #firstname VARCHAR(MAX)
DECLARE #middlename VARCHAR(MAX)
DECLARE #lastname VARCHAR(MAX)
set #firstname = 'FirstName'
set #middlename = NULL
set #lastname = 'LastName'
SELECT '|'+RTRIM(LTRIM(RTRIM(isnull(#firstname,'') + ' ' + isnull(#middlename,'')) + ' ' + isnull(#lastname,'')))+'|'
--
If you are using SQL Server 2012+ you could use CONCAT and +:
SELECT RTRIM(
CONCAT(FirstName + ' ', MiddleInitial + ' ', LastName + ' ', Suffix)
) AS [FullName]
FROM tbl_Contacts;
How it works:
If any part of full name is NULL then NULL + ' ' → NULL
CONCAT handles NULL
In case that after part of name there are only NULLs, TRIM last space.
LiveDemo
Here is a solution:
CREATE FUNCTION dbo.udf_IsNullOrEmpty
(
#vchCheckValue VARCHAR(MAX)
,#vchTrueValue VARCHAR(MAX)
,#vchFalseValue VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
RETURN CASE WHEN NULLIF(RTRIM(LTRIM(#vchCheckValue)),'') IS NULL THEN #vchTrueValue ELSE #vchFalseValue END
END
SELECT FirstName + ' ' +
dbo.udf_IsNullOrEmpty(MiddleInitial,'',MiddleInitial + ' ') +
LastName +
dbo.udf_IsNullOrEmpty(Suffix,'',' ' + Suffix)
FROM tbl_Contacts
select CONCAT(IFNULL(FirstName, ''),
'',
IFNULL(MiddleName, ''),
'',
IFNULL(LastName, '')) AS name
from table
Why not like this:
select concat(fName,' ',
case length(mName)
when 0 then ''
else concat(mName, ' ') end, lName) as fullName
My columns are not null, so this works for me.
create function getfname(#n varchar(30))
returns varchar(30)
as
begin
declare #s varchar(30)
set #s=LEFT(#n,charindex(' ',#n)-1)
return #s
end
create function getLname(#n varchar(30))
returns varchar(30)
as
begin
declare #s varchar(30)
set #s=substring(#n,charindex(' ',#n+1),Len(#n))
return #s
end
the query:
SELECT retire.employeehrmsid,
Isnull(retire.firstname, '') + ' '
+ Isnull(retire.middlename, '') + ' '
+ Isnull(retire.lastname, '') AS FullName,
retire.dojtoservice,
retire.designation,
emphistory.currentdoj,
emphistory.presentddo,
emphistory.office,
transfer.generatetid AS TransferID,
transfer.transferdate,
transfer.currentlocation,
transfer.newlocation,
transfer.datas AS Transfer_Doc,
release.generaterid AS ReleaseID,
release.releasedate,
release.datar AS Release_Doc,
employeeserviceupdate.dataeu AS Join_Doc
FROM retire
INNER JOIN emphistory
ON retire.id = emphistory.id
INNER JOIN employeeserviceupdate
ON retire.id = employeeserviceupdate.id
INNER JOIN transfer
ON retire.id = transfer.id
AND emphistory.ehrid = transfer.ehrid
INNER JOIN release
ON transfer.tid = release.tid
3 fields: FirstName, MiddleName, LastName
Any field can be null, but I don't want extra spaces. Format should be "First Middle Last", "First Last", "Last", etc.
LTRIM(RTRIM(
LTRIM(RTRIM(ISNULL(FirstName, ''))) + ' ' +
LTRIM(RTRIM(ISNULL(MiddleName, ''))) + ' ' +
LTRIM(ISNULL(LastName, ''))
))
NOTE: This won't leave trailing or leading spaces. That's why it's a little bit uglier than other solutions.
Assuming by "extra spaces", you mean extra spaces inserted during the concatenation (which is a reasonable assumption, I think. If you have extra spaces in your data, you should clean it up):
ISNULL(FirstName + ' ', '') + ISNULL(MiddleName + ' ', '') + ISNULL(LastName, '')
works, since you'll add a space to the name - which if it's NULL yields NULL - which yields empty string.
Edit: If you don't count the SET OPTION - which can be a connection or db option:
SET CONCAT_NULL_YIELDS_NULL OFF
LTRIM(FirstName + ' ' + NULLIF(MiddleName + ' ', ' ') + LastName)
is a tiny bit shorter, but a large bit uglier.
Edit2: Since you accepted the UDF answer - IMO, that's a bit of a cheat - here's some in the same vein:
SELECT a FROM b
b is a view. ;) Or. a stored proc,
EXEC c
But, since EXEC is optional:
c
use a UDF:
`Select udfConcatName(First, Middle, Last) from foo`
That way all your logic for concatenating names is in one place and once you've gotten it written it's short to call.
LTRIM(RTRIM(ISNULL(FirstName, '') + ' ' + LTRIM(ISNULL(MiddleName, '') + ' ' +
ISNULL(LastName, ''))))
Why not use a computed column on the table that performs the concat for you using your preferred syntax from the many posted here? Then you will just query the computed column - very elegant and if you persist the computed column then you may even get slight performance increase.
Example here
replace(ltrim(rtrim(isnull(FirstName, '') + ' ' + isnull(MiddleName, '') + ' ' + isnull(LastName, ''))), ' ', ' ')
'"' + ltrim(rtrim(isnull(FirstName,''))) + ' ' + ltrim(rtrim(isnull(MiddleName,''))) +
' ' + ltrim(rtrim(isnull(LastName,''))) + '","' + ltrim(rtrim(isnull(FirstName,''))) +
' ' + ltrim(rtrim(isnull(LastName,''))) + '","' + ltrim(rtrim(isnull(LastName,''))) +
'"'
ETC
DECLARE #first varchar(10) = 'First'
DECLARE #middle varchar(10) = ''
DECLARE #last varchar(10) = 'Last'
LTRIM(RTRIM(
#first
+ ISNULL(NULLIF(' '+LTRIM(RTRIM(#middle)),' '),'')
+ ISNULL(NULLIF(' '+LTRIM(RTRIM(#last)),' '),'')
))
WHY THIS WORKS
The fields are reduced to an empty string if NULL or whitespace by the LTRIM, RTRIM, and ISNULL functions.
LTRIM(RTRIM(ISNULL(#middle,''))) -- Result is a trimmed non-null string value.
That value is prefixed with a single space, then compared to a single space by the NULLIF function. If equal, a NULL results. If not equal, then the value is used.
NULLIF(' '+'',' ') -- this would return NULL
NULLIF(' '+'Smith',' ') -- this would return ' Smith'
Finally, ISNULL() is used to convert the NULL passed by NULLIF to an empty string.
ISNULL(NULL,'') -- this would return ''
ISNULL(' Smith','') -- this would return ' Smith'
LTrim(RTrim(Replace(IsNull(Firstname + ' ', '') +
isNull(MiddleName, '') +
IsNull(' ' + LastName, ''), ' ', ' ')))
Select firstname, middlename, lastname, ProvidedName =
RTrim(Coalesce(FirstName + ' ','')
+ Coalesce(MiddleName + ' ', '')
+ Coalesce(LastName + ' ', '')
+ COALESCE('' + ' ', '')
+ COALESCE(NULL, ''))
From names