How join columns with null value? - sql

Hi please help me. How join 3 columns with null values?.
SELECT [item],[Prox],[z], [item]+[Prox]+[z] as result FROM [FIELD$];
Result.

Try this:
SELECT [item],[Prox],[z], COALESCE([item],'')+COALESCE([Prox],'')+COALESCE([z],'') as result
FROM [FIELD$];
Explanation:
COALESCE evaluates the arguments in order and returns the current value of the first expression that initially does not evaluate to NULL.
i.e., If [item] is NULL, then COALESCE([item],'') will return an empty string.
Other alternatives:
Instead of COALESCE(ColName,''), you can use:
ISNULL(ColName,'') for SQL Server.
IFNULL(ColName,'') for MySQL.
NVL(ColName,'') for Oracle.

As concatenating multiple strings with at least one null value results in NULL you may use coalesce to solve this:
SELECT
[item],
[Prox],
[z],
coalesce([item], '') + coalesce([Prox], '') + coalesce([z], '') as result
FROM
[FIELD$];
coalesce is ANSI standard and available in almost all reasonable databases.

IN SQL Server 2012, you can use CONCAT function:
SELECT [item],[Prox],[z], concat([item],[Prox],[z]) as result FROM [FIELD$];

Related

Replacing "(null)" with blank cell in SQL query result

I believe what I'm asking here is possible, but I haven't find a way yet :
Some cells in the result of my SQL SELECT-FROM-WHERE query are blank, and in DbVisualizer, (null) is written inside. I'd like to display a blank cell instead.
I've already tried with CASE-WHEN and the NVL operator, but it won't let me replace it by a blank '', I'm forced to use some ' ' or 'message'.
I know I could just delete these spaces or messages with Excel later, but I'd like to know if there is a way to do it directly with DbVisualizer, instead of this workaround.
EDIT: Here is what my request looks like :
SELECT *things*,
CASE WHEN
(SELECT COUNT(*) FROM table d2 WHERE *join-condition* AND *other condition*) = 1
THEN
(*sub-select query*)
ELSE
''
END
AS NAME,
*other things*
FROM table d1
WHERE *something*
Thanks a lot !
Did you try standard SQL function coalesce(), as below ?
SELECT COALESCE(columnName, '') AS ColumnName FROM tableName;
Syntax:
COALESCE (expr1, expr2)
is equivalent to:
CASE WHEN expr1 IS NOT NULL THEN expr1 ELSE expr2 END
Similarly,
COALESCE (expr1, expr2, ..., exprn), for n>=3
is equivalent to:
CASE WHEN expr1 IS NOT NULL THEN expr1
ELSE COALESCE (expr2, ..., exprn) END
Above examples are from Database SQL Language Reference
The problem in your query is the following ELSE part of the CASE expression:
ELSE
''
In Oracle, an empty string is considered as NULL value. So, all you need to do is use something else instead of ''.
For example, to use a space instead of NULL:
ELSE
' '
Update The issue is the DbVisualizer tool. OP is on version 8.0.12. Prior to version 9.2.8 it cannot show NULL as an empty string. However, as discussed in this forum, it has been fixed in DbVisualizer 9.2.8.
Standard SQL provides COALESCE(expr1, expr2, ...) as suggested by #Shishir.
COALESCE() takes a variable amount of arguments and returns the first expression that is NOT NULL
MySQL also provides IFNULL(expr1,expr2), which returns expr2 when expr1 IS NULL
Examples
SELECT
COALESCE(field1, ''),
COALESCE(field1, field2, field3)
IFNULL(field1, ''),
IFNULL(field1, field2)
FROM table

Handling NULL in Sql server string concatenation

I have the following SQL query
select s.comments + s.further_comments from dbo.samples s where id = 1234
However if s.comments or s.further_comments is NULL the whole string is returned NULL
How do I convert the NULL value to an empty string or at least only return the non NULL values in this string?
You can use either ISNULL or COALESCE for this.
SELECT ISNULL(s.comments, '') + ISNULL(s.further_comments, '')
SELECT COALESCE(s.comments, '') + COALESCE(s.further_comments, '')
ISNULL
Replaces NULL with the specified replacement value.
COALESCE
Returns the first nonnull expression among its arguments.
Note that there are some differences between the two methods but for all intents and purposes, they most likely don't apply to your situation.
ISNULL(NULL, NULL) -- is int
COALESCE(NULL, NULL) -- Will throw an error
COALESCE(CAST(NULL as int), NULL) -- it valid and returns int
ISNULL takes only 2 parameters whereas COALESCE takes variable number of parameters
COALESCE is based on the ANSI SQL standard whereas ISNULL is a proprietary TSQL function

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

How to replace null into 0 in a complex query

I would like to replace the total value to 0 when it is null
Here is the query:
SELECT DISTINCT(location), (
SELECT Count(a.location) as total
FROM table_fo a
LEFT JOIN table_info b ON a.TRADEID = b.TRADEID AND a.asofdate = b.asofdate
WHERE (b.TERMSTATUS <> 'TRAN' OR b.TERMSTATUS is NULL) AND b.asofdate = '20110105' AND a.location = pfo.location
GROUP BY a.LOCATION
) AS total
FROM table_fo pfo
WHERE asofdate = '20110105';
You can use the ISNULL function.
Here is how you will use the function (for SQL Server).
ISNULL(columnName, 0)
I would like to replace the total
value to 0 when it is null
This is an impossible situation because:
The COUNT function always returns an integer. The result cannot be NULL!
As for coalescing an expression to a certain default in case it is NULL there are functions that do this in all major databases (ex.: COALESCE, NVL, ISNULL, IFNULL). The typical use is
FUNCTION_NAME(ExpressionThatMayBeNULL, DefaultWhenNull)
For specifics you should consult you database manufacturers documentation (you can find it online).
COALESCE will do this in PL/SQL (Oracle) and T-SQL (SQL Server)
Syntax is COALESCE(field1, field2[, fieldN]) - it will select the first column from the left to have a non-null value.
Modifying the query you had:
SELECT DISTINCT(location), COALESCE((
SELECT Count(a.location) as total
FROM table_fo a
LEFT JOIN table_info b ON a.TRADEID = b.TRADEID AND a.asofdate = b.asofdate
WHERE (b.TERMSTATUS <> 'TRAN' OR b.TERMSTATUS is NULL) AND b.asofdate = '20110105' AND a.location = pfo.location
GROUP BY a.LOCATION
),0) AS total
FROM table_fo pfo
WHERE asofdate = '20110105';
As dparker said, ISNULL(...) will work for some types of sql, though the name of the function can vary among database providers.
The function in IBM DB2 is called COALESCE(...), and in Oracle SQL it is NVL(...) for example.
This may be usefull
http://www.w3schools.com/sql/sql_isnull.asp
If you are using SQL server, the following are the 3 ways that can be used to replace a null with any user defined substitute value.
1. ISNULL
2. COALESCE
3. CASE
This question is also asked in one of the interviews I attended. Here is the link for an article with examples. By the way, there's also a video on the same in this article.
Different ways to replace NULLS in SQL Server
What DB system are you using?
SQL-Server, MySQL: IFNULL(value, 0)
Oracle: NVL(value, 0)
PostgreSQL: COALESCE(value, 0)

How to check if a string is a uniqueidentifier?

Is there an equivalent to IsDate or IsNumeric for uniqueidentifier (SQL Server)?
Or is there anything equivalent to (C#) TryParse?
Otherwise I'll have to write my own function, but I want to make sure I'm not reinventing the wheel.
The scenario I'm trying to cover is the following:
SELECT something FROM table WHERE IsUniqueidentifier(column) = 1
SQL Server 2012 makes this all much easier with TRY_CONVERT(UNIQUEIDENTIFIER, expression)
SELECT something
FROM your_table
WHERE TRY_CONVERT(UNIQUEIDENTIFIER, your_column) IS NOT NULL;
For prior versions of SQL Server, the existing answers miss a few points that mean they may either not match strings that SQL Server will in fact cast to UNIQUEIDENTIFIER without complaint or may still end up causing invalid cast errors.
SQL Server accepts GUIDs either wrapped in {} or without this.
Additionally it ignores extraneous characters at the end of the string. Both SELECT CAST('{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss' as uniqueidentifier) and SELECT CAST('5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' as uniqueidentifier) succeed for instance.
Under most default collations the LIKE '[a-zA-Z0-9]' will end up matching characters such as À or Ë
Finally if casting rows in a result to uniqueidentifier it is important to put the cast attempt in a case expression as the cast may occur before the rows are filtered by the WHERE.
So (borrowing #r0d30b0y's idea) a slightly more robust version might be
;WITH T(C)
AS (SELECT '5D944516-98E6-44C5-849F-9C277833C01B'
UNION ALL
SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}'
UNION ALL
SELECT '5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
UNION ALL
SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss'
UNION ALL
SELECT 'ÀD944516-98E6-44C5-849F-9C277833C01B'
UNION ALL
SELECT 'fish')
SELECT CASE
WHEN C LIKE expression + '%'
OR C LIKE '{' + expression + '}%' THEN CAST(C AS UNIQUEIDENTIFIER)
END
FROM T
CROSS APPLY (SELECT REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]') COLLATE Latin1_General_BIN) C2(expression)
WHERE C LIKE expression + '%'
OR C LIKE '{' + expression + '}%'
Not mine, found this online... thought i'd share.
SELECT 1 WHERE #StringToCompare LIKE
REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
SELECT something
FROM table1
WHERE column1 LIKE '[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]';
UPDATE:
...but I much prefer the approach in the answer by #r0d30b0y:
SELECT something
FROM table1
WHERE column1 LIKE REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
I am not aware of anything that you could use "out of the box" - you'll have to write this on your own, I'm afraid.
If you can: try to write this inside a C# library and deploy it into SQL Server as a SQL-CLR assembly - then you could use things like Guid.TryParse() which is certainly much easier to use than anything in T-SQL....
A variant of r0d30b0y answer is to use PATINDEX to find within a string...
PATINDEX('%'+REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]')+'%',#StringToCompare) > 0
Had to use to find Guids within a URL string..
HTH
Dave
Like to keep it simple. A GUID has four - in it even, if is just a string
WHERE column like '%-%-%-%-%'
Though an older post, just a thought for a quick test ...
SELECT [A].[INPUT],
CAST([A].[INPUT] AS [UNIQUEIDENTIFIER])
FROM (
SELECT '5D944516-98E6-44C5-849F-9C277833C01B' Collate Latin1_General_100_BIN AS [INPUT]
UNION ALL
SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}'
UNION ALL
SELECT '5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
UNION ALL
SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss'
UNION ALL
SELECT 'ÀD944516-98E6-44C5-849F-9C277833C01B'
UNION ALL
SELECT 'fish'
) [A]
WHERE PATINDEX('[^0-9A-F-{}]%', [A].[INPUT]) = 0
This is a function based on the concept of some earlier comments. This function is very fast.
CREATE FUNCTION [dbo].[IsGuid] (#input varchar(50))
RETURNS bit AS
BEGIN
RETURN
case when #input like '[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]'
then 1 else 0 end
END
GO
/*
Usage:
select [dbo].[IsGuid]('123') -- Returns 0
select [dbo].[IsGuid]('ebd8aebd-7ea3-439d-a7bc-e009dee0eae0') -- Returns 1
select * from SomeTable where dbo.IsGuid(TableField) = 0 -- Returns table with all non convertable items!
*/
DECLARE #guid_string nvarchar(256) = 'ACE79678-61D1-46E6-93EC-893AD559CC78'
SELECT
CASE WHEN #guid_string LIKE '________-____-____-____-____________'
THEN CONVERT(uniqueidentifier, #guid_string)
ELSE NULL
END
You can write your own UDF. This is a simple approximation to avoid the use of a SQL-CLR assembly.
CREATE FUNCTION dbo.isuniqueidentifier (#ui varchar(50))
RETURNS bit AS
BEGIN
RETURN case when
substring(#ui,9,1)='-' and
substring(#ui,14,1)='-' and
substring(#ui,19,1)='-' and
substring(#ui,24,1)='-' and
len(#ui) = 36 then 1 else 0 end
END
GO
You can then improve it to check if it´s just about HEX values.
I use :
ISNULL(convert(nvarchar(50), userID), 'NULL') = 'NULL'
I had some Test users that were generated with AutoFixture, which uses GUIDs by default for generated fields. My FirstName fields for the users that I need to delete are GUIDs or uniqueidentifiers. That's how I ended up here.
I was able to cobble together some of your answers into this.
SELECT UserId FROM [Membership].[UserInfo] Where TRY_CONVERT(uniqueidentifier, FirstName) is not null
Use RLIKE for MYSQL
SELECT 1 WHERE #StringToCompare
RLIKE REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
In a simplest scenario. When you sure that given string can`t contain 4 '-' signs.
SELECT * FROM City WHERE Name LIKE('%-%-%-%-%')
In BigQuery you can use
SELECT *
FROM table
WHERE
REGEXP_CONTAINS(uuid, REPLACE('^00000000-0000-0000-0000-000000000000$', '0', '[0-9a-fA-F]'))