Concatenating null to string using + results in null - sql

I have the following SQL Query in Access:
SELECT ID, CurrencyName + ' (' + CurrencySymbol + ')' AS [Currency],
CurrencyLocation, CurrencySymbol FROM Currencies ORDER BY SortOrder
What I noticed is that I get a full table of results except if if the field CurrencySymbol is left NULL or empty. If the CurrencySymbol field is null, rather than Concatenate nothing, Access skips over the record and continues as shown below
.
Did I get something wrong or is there a better way to write this Query?

If you concatenate strings with +, string + NULL yields NULL.
If you concatenate strings with &, string & NULL yields string.
Thus, you have two options to fix this:
Option 1: CurrencyName + ' (' + Nz(CurrencySymbol, '') + ')'. Nz (NullToZero) converts Null values to its second argument.
Option 2: CurrencyName & ' (' & CurrencySymbol & ')'
You can use this fact to create an expression that only shows the parenthesis when a currency symbol is present (Credit for this idea goes to this blog post):
CurrencyName & (' (' + CurrencySymbol + ')') will yield Points and Euro (€).

That's because concatenating a string and NULL results in NULL.
SELECT ID, CurrencyName + ' (' + Iif(IsNull(CurrencySymbol), '', CurrencySymbol) + ')'
AS [Currency], CurrencyLocation, CurrencySymbol
FROM Currencies
ORDER BY SortOrder

Related

SQL subtracting a string column from another string column

I am looking to subtract two string columns from another string column.
I have acheived this in the past in Oracle using the below
SELECT
C.MANUFACTURER,
C.MODEL_GROUP,
REGEXP_REPLACE(C.VARIANT, '^'||C.MANUFACTURER || ' +' || C.MODEL_GROUP) "VAR DESC",
C.VARIANT
FROM STD_BI.RL2_CONTRACTS_VW C
I now need to acheive the same in MS SQL any suggestions would be appreciated.
"Subtract" is surely a misnomer here. The OP appears to want to remove a string at the beginning of another string.
From this point on, I am assuming that MANUFACTURER and MODEL_GROUP do not contain any regular expression wildcard characters.
There is a challenge with multiple spaces. If there are not too many, then you can do. For instance, this handles one or two spaces:
SELECT C.MANUFACTURER, C.MODEL_GROUP,
(CASE WHEN C.VARIANT LIKE C.MANUFACTURER + ' ' + C.MODEL_GROUP + '%'
THEN STUFF(C.VARIANT, 1, LEN(C.MANUFACTURER + ' ' + C.MODEL_GROUP), '')
WHEN C.VARIANT LIKE C.MANUFACTURER + ' ' + C.MODEL_GROUP + '%' AND
THEN STUFF(C.VARIANT, 1, LEN(C.MANUFACTURER + ' ' + C.MODEL_GROUP), '')
ELSE C.VARIANT
END) as [VAR DESC],
C.VARIANT
FROM STD_BI.RL2_CONTRACTS_VW C;
EDIT:
Here is a more complete solution:
SELECT C.MANUFACTURER, C.MODEL_GROUP,
(CASE WHEN C.VARIANT LIKE C.MANUFACTURER + ' %' + C.MODEL_GROUP + '%' AND
C.VARIANT NOT LIKE C.MANUFACTURER + ' %[^ ]%' + C.MODEL_GROUP + '%'
THEN STUFF(LTRIM(STUFF(C.VARIANT, 1, LEN(C.MANUFACTURER), '')), 1, LEN(C.MODEL_GROUP), '')
ELSE C.VARIANT
END) as [VAR DESC],
C.VARIANT
FROM STD_BI.RL2_CONTRACTS_VW C;
This tests for just spaces between the two strings (the not like is checking for something other than a space). The replacement is then in three steps -- remove the manufacturer, then the spaces, then the model group.
I have spent some time on this one as much for my own satisfaction and in addition to the answer above, I have come up with the following which also generates the correct answer.
SUBSTRING(FV.VARIANT, LEN(FV.MANUFACTURER + ' ' + FV.MODEL_RANGE + ' ') + 1 , LEN(FV.VARIANT))
My problem was kinda easier to solve, I just needed to remove "xxxx" (the first 4 characters) at the start of a column from some rows:
UPDATE coluna SET columToEdit = SUBSTRING(columToEdit, 5, 200);

How do I catch a handle a null value in a concatenated string?

I have the following in a view
c2.title + ' ' + c2.initials + ' ' + c2.surname AS referredTo
As it stands now, if one of those values are null, then referredTo is just null. But for some of the records, the title, the initials, or the surname may be null. What is the best way to handle this so that is one or more of the values are null, it will return only the string with the non-null values. So for example, if title is null, it will only return "initals surname", if initials is null, it will return "title surname", if both are null, it will return "surname", etc, to cover any of those values being null. This is probably a really easy answer but I'm kinda new to SQL and having to learn as I go.
Thanks.
As suggested in the comment, put the White Space within the ISNULL:
SELECT ISNULL(Title + ' ', '') + ISNULL(Initials + ' ','') + ISNULL(Surname,'')
FROM YourTable;
That means that you don't end up with WhiteSpace at the front, or (possibly) two spaces between Title and Surname if Initials has a value of NULL.
Maybe you can use ISNULL, please check following statement
RTRIM(
LTRIM(
ISNULL(c2.title, '') + ' ' +
ISNULL(c2.initials, '') + ' ' +
ISNULL(c2.surname, '')
)
) AS referredTo
SET #FinalAnswer= ISNULL(#Col1, '') + ' ' +ISNULL(#Col2, '')
Try above approach.
Use Concat()
Select LTRIM(RTRIM(Concat(c2.title,' ',c2.initials,' ',c2.surname))) AS referredTo
FROM yourTable
DEMO

SELECT DISTINCT is omitting NULL values when not desired

I am trying to build a distinct string in a query, which works unless one of the values is NULL. I've tested removing LOCATION_ADDR_LINE_2, and the query will work just fine. When I do not SELECT DISTINCT, I find that LOCATION_ADDR_LINE_2 values are NULL. How can I gather these values in the SELECT DISTINCT even if NULL?
SELECT DISTINCT(LOCATION_ADDR_LINE_1 + ', ' + LOCATION_ADDR_LINE_2 + ', ' + LOCATION_CITY + ', ' + LOCATION_WORK_STATE) AS Addresses
FROM OracleReport
WHERE (LOCATION_ADDR_LINE_1 LIKE '%1135 Auto%' OR LOCATION_ADDR_LINE_1 LIKE '%199 Easy%')
Returns:
Addresses
NULL
SELECT DISTINCT(LOCATION_ADDR_LINE_1 + ', ' + LOCATION_CITY + ', ' + LOCATION_WORK_STATE) AS Addresses
FROM [OperationReport].[dbo].[OracleReport]
WHERE (LOCATION_ADDR_LINE_1 LIKE '%1135 Auto%' OR LOCATION_ADDR_LINE_1 LIKE '%199 Easy%')
Returns:
Addresses
1135 Auto...
189-199 Easy...
Assuming you don't mind text,,text,... (empty string) when a value is NULL...
SELECT DISTINCT(coalesce(LOCATION_ADDR_LINE_1,'') + ', ' +
coalesce(LOCATION_ADDR_LINE_2,'') + ', ' +
coalesce(LOCATION_CITY,'') + ', ' +
coalesce(LOCATION_WORK_STATE,'')) AS Addresses
FROM OracleReport
WHERE (LOCATION_ADDR_LINE_1 LIKE '%1135 Auto%'
OR LOCATION_ADDR_LINE_1 LIKE '%199 Easy%')
Coalesce will take the first non-null value and return it. It requires consistent data types and will early exit once the first non-null value in a series is encountered. (more details Oracle Differences between NVL and Coalesce)

TSQL get data regardless of Null value

I have a stored procedure that is getting information from my employee table and returning the data.
There are 3 columns that are used:
B.[SiloDesc] + ' (' + B.[TitleDesc] + ') ' + B.[SkillSetDesc] as SkillSetDesc,
My issue is, if one of those happens to be null, it wont display any of the data. What is the best way to have it include the data regardless of if one of those fields are null.
You could use coalesce() or isnull() for each individual column... or you could simply use...
CONCAT ( string_value1, string_value2 [, string_valueN ] )
Takes a variable number of string arguments and concatenates them into a single string. It requires a minimum of two input values; otherwise, an error is raised. All arguments are implicitly converted to string types and then concatenated. Null values are implicitly converted to an empty string.
A.: Remove the parentheses when TitleDesc is null:
select concat(B.[SiloDesc], ' (' + B.[TitleDesc] + ')', ' ' + B.[SkillSetDesc])
Because of the way null is treated in sql, the expression ' (' + null + ')' results in null which concat() will treat as an empty string... which is kind of nice as it effectively removes the parentheses if the value is null.
B.: Keep the parentheses regardless:
select concat(B.[SiloDesc], ' (', B.[TitleDesc], ') ', B.[SkillSetDesc])
Samples:
select concat('john', ' (' + null + ')', ' adams') -- john adams
select concat('john', ' (test)', ' ' + null) -- john (test)
select concat('john', ' (the man)', ' adams') -- john (the man) adams
isnull(B.[SiloDesc], '')
+ ' (' + isnull(B.[TitleDesc], '') + ') '
+ isnull(B.[SkillSetDesc], '') as SkillSetDesc,

How to evenly space 3 concatenated fields in the result set

I have three fields that I concatenated into one field, but when I run the query the result-set is correct, but they are not evenly spaced within the one field. How would I space them neatly and correctly. Thank-you for the help.
Here is the query:
SELECT CONVERT(varchar(20),Book)+ Space(2) + '(' + CONVERT(varchar(30),Year)
+ ')' + Space(2) + '(' + CONVERT(varchar(30),Print) + ')' As 'Film Description', Genre,
Cost
FROM Film
Order By Year DESC, Book ASC
Since VARCHAR ignores trailing spaces, you need to use a different data type that doesn't (e.g. CHAR). A few other comments:
be careful about using reserved words such as year and print as column names
be careful about using 'single quotes' as alias delimiters ([square brackets] are more future-proof and harder to muddle with string literals)
you should use the schema prefix (e.g. dbo.Film)
DECLARE #Film TABLE(Book VARCHAR(255), [Year] INT, [Print] VARCHAR(255));
INSERT #Film
SELECT 'a', 2012, 'hello there this is at least 30 characters, right?'
UNION ALL
SELECT 'this must be at least 30 characters too, right?', 2011, 'b';
SELECT CONVERT(CHAR(20), Book)
+ SPACE(2)
+ '(' + CONVERT(CHAR(4),[Year]) + ')'
+ SPACE(2)
+ '(' + CONVERT(CHAR(30), [Print]) + ')'
As [Film Description]
FROM #Film
Order By [Year] DESC, Book;
Use Convert(Char( instead of Convert(Varchar(
Varchars have the spaces stripped off..