DATALENGTH() or ISNULL() to retrieve fields that are not null and not empty - sql

Quite simply, which of the following methods is better in a WHERE clause to retrieve records where the FIELD_NAME is NOT NULL and NOT Empty
WHERE DATALENGTH(FIELD_NAME) > 0
or
WHERE ISNULL(FIELD_NAME, '') <> ''
Update
I have been informed that the first method gives spurious results for some types of fields... Agree?

Firstly,
select *
from table
where column <> ''
will give exactly the same results as
select *
from table
where isnull(column, '') <> ''
because records where the condition is UNKNOWN rather than FALSE will still be filtered out. I would generally go with the first option.
DATALENGTH counts trailing spaces, which a comparison with '' does not. It is up to you whether you want ' ' to compare unequal to ''. If you do, you need DATALENGTH. If you don't, simply compare with ''.
Note that for TEXT/NTEXT types, comparisons are not supported, but DATALENGTH is.

ISNULL is the best approach instead of DATALENGTH.

I would use
WHERE ISNULL(FIELD_NAME, '') <> ''
One issue that might come up is that a record with a space in it would not be returned. Are you looking for records like that?
I'm not sure about unexpected results from DATALENGTH. I would use the ISNULL method so that SQL Server doesn't need to spend time calculating the length of the record being compared. I don't know the performance difference between the two, just a gut feeling.

if your "not empty" condition encompasses spaces then i would use the nullif
select case when nullif(' ', '') is null then 'y' else 'n' end
y
declare #d varchar(50)
set #d = null
select case when nullif(#d, '') is null then 'y' else 'n' end
y

I would use one of the following:
where coalesce(field_name, '') <> ''
or
where field_name <> '' or field_name is not null
or
where field_name <> ''
The first is standard SQL (coalesce() is standard, isnull() is not). The last is not the most obvious, but NULL will fail the comparison and it allows the use of indexes.

RTRIM(LTRIM(ISNULL(FIELD_NAME, ''))) <> '' will handle spaces and NULLS

Related

Removing specified character from string in SQL

Say I have a string looking like this ",LI,PA,LK";
I want to remove the first char, so it looks like "LI,PA,LK";
In Java my code to handle this, will look like this:
public String returnSubs(String val) {
int index = val.indexOf(",");
String res = val.substring(index+1, val.length());
return res;
}
I want to achieve the exact same thing in SQL, having this query
select patientID, case when liver is not null then 'LI' else '' end
|| case when kidney_r is not null then ',KR' else '' end
|| case when kidney_l is not null then ',KL' else ''end
|| case when heart is not null then ',HE' else '' end
|| case when liver_domino is not null then ',LI-Dom' else '' end
|| case when lung_r is not null then ',LungR' else '' end
|| case when pancreas is not null then ',PA' else '' end
|| case when liver_split is not null then ',Lsplit' else '' end
|| case when lung_l is not null then ',LungL' else '' end
|| case when intestine is not null then ',Intestine' else '' end
into organType
from offers
where patientID > 1
;
Also, the string I get from the query above, could look like LI, PA, KL, (notice the comma is at the end, and not the begining)
I see that I can use the SUBSTRING and/or INSTR of SQL. But I'm not really sure how. I am creating a procedure where this will be handled
Thanks for any help
Oracle has a function trim() that does exactly what you want:
trim(leading ',' from col)
You can use this in either an update or select.
Note: You appear to be storing multiple values in a comma-delimited list. That is a very bad way to model data. You do not want to overload what strings are by storing multiple values. Oracle has many better alternatives -- association tables, nested tables, JSON, and XML come to mind.
You could also use LTRIM here:
SELECT
LTRIM(organTypes, ',') AS col_out
FROM offers;
Some databases, such as MySQL, offer functions like CONCAT_WS which concatenate with a separator while ensuring that no dangling separators are added to the resulting output. Oracle does not have this, but LTRIM should be sufficient here.
even this will work:
substr(',LI,PA,LK',2)
In SQL SERVER:
SUBSTRING(VAL,2,LEN(VAL))
VAL--> COLUMN NAME
2--> IT SKIPS 1ST VALUE
LEN-->LENGTH OF THE COLUMN

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).

SQL: How to make a replace on the field ''

I have a very but tricky question for you guys. So, listen I have a field with spaces and numbers in one of my table columns. The key part is transform the content in a decimal field. The drawback is basically that for some rows I could get something like:
' 1584.00 '
' 156546'
'545.00 '
' '
So, to clean up my column, I have done a LTRIM and RTRIM so spaces gone. So now for a couple of records where the record were just spaces the new content is ''. Finally I need to convert this result to a decimal.
Issue: The thing is that for field that contend just the spaces the new result is '' and I'm not able to apply a REPLACE on this because it's a blank and the code below doesn't work:
SELECT REPLACE('','','0')
-- Final current verison
SELECT CAST(COALESCE(REPLACE(REPLACE([Gross_Weight],' ','0'),',',''),'0') AS DECIMAL(13,3))
How could I figure it out?
thanks so much
SELECT COALESCE(NULLIF(MyColumn, ''), 0)
This has the side-effect that you will also turn NULL values into 0, which you might not want. If that's a problem then a simple CASE statement should do the trick:
SELECT CASE WHEN MyColumn = '' THEN 0 ELSE CAST(MyColumn AS DECIMAL(10, 4)) END
Obviously you'll also have to incorporate any other manipulations that you're already doing.
No need for replace, just concatenate a zero to your column, like
SELECT RTRIM('0' + LTRIM(column))
I presume your data is in a table.
Lets call this table 'DATA' and the column 'VALUE'
Then you might use the below query
UPDATE DATA SET VALUE = 0 where VALUE = ''
To select the value do the below
select case ltrim(rtrim([Gross_Weight])) when ''
THEN 0
ELSE ltrim(rtrim([Gross_Weight])) END
Let me know if i get the requirement wrong.

TSQL Comparing 2 uniqueidentifier values not working as expected

I'm trying to compare 2 uniqueidentifier values as shown in the query below. However, if one value is null and one value isn't, the result is 'same'?! I'm sure that both values are uniqueidentifiers, and have also tried casting both values to uniqueidentifier to make absolutely sure. The 2 values being compared are coming from different databases with different collations. Does the collation make any difference? Any ideas would be appreciated.
select [result] = case when
[target].StaffID <> [source].StaffID then 'different'
else 'same'
end
from
...
If I replace the <> with an = the query then thinks that 2 null values don't match.
EDIT:
I used:
declare #empty uniqueidentifier
set #empty = '00000000-0000-0000-0000-000000000000'
... isnull(somevalue, #emtpy) <> isnull(othervalue, #empty) ...
NULL is neither equal to something nor equal to nothing. Generally you'd check for null values by comparing with IS NULL. For example,
somefield IS NULL
You could look into using COALESCE for what you're trying to do -- just make sure you use the same data types (in this case UniqueIdentifier):
...
case
when coalesce(t.StaffID,'00000000-0000-0000-0000-000000000000') <>
coalesce(t2.StaffID,'00000000-0000-0000-0000-000000000000')
then 'different'
else 'same'
end
...
http://sqlfiddle.com/#!3/181e9d/1
null is more of an unknown, it's not really a value. Unfortunately SQL will tell you that null = null is false.
Basically you have to cast nulls to empty strings than you can compare. We use IFNULL(value, replacement) to do that...
http://msdn.microsoft.com/en-us/library/ms184325.aspx
Hope this helps.
select case when null = null then 'equal' else 'not equal' end
Above will be "not equal"
select case when ISNULL(null, '') = ISNULL(null, '') then 'equal' else 'not equal' end
This one will be "equal"
And finally your case...
select [result] = case when
ISNULL([target].StaffID, '') <> ISNULL([source].StaffID, '') then 'different'
else 'same'
end
from

Optimization of SQL

I have a query regarding a sql query where i have 3 conditions on same column
AND TRP.X_ID <> '0'
AND TRP.X_ID <> ' '
AND TRP.X_ID IS not NULL;
can this be handled with 1 or 2 conditions within where clause.
Well, if a column is currently NULL, it is never equal, not not equal, to any specific value, so you can skip the 3rd test immediately. As for the other two, you can condense it to:
TRP.X_ID not in ('0',' ')
which is shorter to read, but unlikely to change how the code performs - in e.g. SQL Server, it's internally re-written back into individual comparisons.
and coalesce(trp.x_id, '') not in ('', '0')
EDIT
or (mysql version)
length(case trp.x_id when '0' then '' else trp.x_id end) > 0
You can also do this... this is really just a syntactical optimization... sql optimizer will interpret these equally (as far as performance).
AND NULLIF(NULLIF(TRP.X_ID,'0'),' ') IS NOT NULL