SQL Doesnt Want to match strings with spaces for some reason - sql

I have this SQL Query that is not comparing properly so I commented it out the WHERE clause. When returning the AF.ActivityNote it always has 2 spaces after it no matter if I do RTRIM on it or not. I think those spaces are the issue that wont let the commented WHERE clause to properly match the string against userfield33.
SELECT CAST(UF.UserField33 AS NVARCHAR) , RTRIM(CAST(AF.ActivityNote AS NVARCHAR))
FROM [BCMTEST01].[dbo].[ActivityContacts] as AC INNER JOIN [BCMTEST01].[dbo].[ActivityFullView] as AF
ON AC.ActivityID = AF.ActivityID INNER JOIN [BCMTEST01].[dbo].[OpportunityExportView] as OP
ON AC.ContactID = OP.ContactServiceID INNER JOIN [BCMTEST01].[dbo].[UserFields] as UF
ON OP.ContactServiceID = UF.ContactServiceID
WHERE ContactID = 8376
--WHERE RTRIM(CAST(UF.UserField33 AS NVARCHAR) = RTRIM(CAST(AF.ActivityNote AS NVARCHAR))
ORDER BY ContactID ASC

First, you should always include the length when converting to nvarchar, varchar, char, and nchar. So use something like:
cast(uf.userfield33 as nvarchar(255)) -- or whatever length you like, so long as you have something
The last two characters are not spaces. Do something like:
select ascii(right( AF.ActivityNote, 1))
To see what the character value is. You can then use replace to get rid of it. Or, you can just chop off the last two characters (if that works for your application).
By the way, I am assuming you are using SQL Server based on the syntax of the query.
Here is an alternative where clause:
where (case when right(AF.ActivityNote, 2) = char(10)+CHar(13)
then LEFT(AF.ActivityNote, LEN(AF.ActivityNote) - 2)
else AF.ActivityNote
end) = CAST(UF.UserField33 AS NVARCHAR(255)
I'm not a big fan of case statements in where clauses. I would actually put the logic in a subquery. Also, I might have the order of the 10/13 backwards.

Related

How to perform Case statement inside a select statement?

I wanted to put 'No record' on the column instead of NULL if the datediff function returns a null value.
SELECT concat(e.firstname ,e.lastname) as Fullname,c.shiftcode as Shift, cast(c.datecheckinout as date) Date,datename(month, c.datecheckinout) as RecordMonth,c.timein , c.timeout,
CAST(
CASE
WHEN (datediff(HOUR,c.timein,c.timeout) IS NULL)
THEN 'No record'
END
), FROM tblCheckInOutDetail c RIGHT JOIN tblEmployee e on e.IdEmployee = c.IdEmployee WHERE e.IdEmployee = 55
So far this code only throws Incorrect syntax near 'CAST', expected 'AS'. but I don't know what data type should I put in the CAST parameter , since if there's a record it will show the datetime .
You need to convert the number value to a string. For this, you can use coalesce():
SELECT concat(e.firstname ,e.lastname) as Fullname,c.shiftcode as Shift, cast(c.datecheckinout as date) Date,datename(month, c.datecheckinout) as RecordMonth,c.timein , c.timeout,
COALESCE(CAST(datediff(HOUR, c.timein, c.timeout) AS VARCHAR(255)), 'No record')
FROM tblEmployee e LEFT JOIN
tblCheckInOutDetail c
ON e.IdEmployee = c.IdEmployee
WHERE e.IdEmployee = 55;
Note: I switched the RIGHT JOIN to a LEFT JOIN. They are equivalent logically. But most people find it much easier to follow the logic of the LEFT JOIN, because the table that defines the rows is the first table being read in the FROM clause.
Strictly answering question (though I don't understand why you need a CASE expression if you have working versions of the query), you can easily translate this to a CASE expression:
ISNULL(CAST(datediff(HOUR,c.timein,c.timeout) as varchar),'No Record')
ISNULL really is just nice, convenient shorthand for CASE WHEN a IS NOT NULL THEN a ELSE b END, so:
CASE WHEN DATEDIFF(HOUR, c.timein, c.timeout) IS NOT NULL
THEN CAST(datediff(HOUR,c.timein,c.timeout) as varchar(11))
ELSE 'No Record' END
As you can see, a downside is that if you really really really want a CASE expression, you have to repeat at least the DATEDIFF to cover both the case where the outer row doesn't exist and the case where the outer row exists but one of the values is NULL.
Also note that you should always specify a length for variable types like varchar, even in cases where you think you're safe with the default.
I don't know if this is the correct option or usage.
but this works for me :
ISNULL(CAST(datediff(HOUR,c.timein,c.timeout) as varchar),'No Record')
But can you guys show me how to do this using case expression?

How to update a column for a set of rows?

The below query gives a set of rows with 3 columns.
Select
c.CaseID, i.ImageID, i.ImagePath
From
tblCase c WITH (NOLOCK)
inner join
tblName n WITH (NOLOCK) on c.CaseID = n.CaseID
inner join
tblImage i WITH (NOLOCK) on n.NameID = i.NameID
where
n.NameCode = '70'
The ImagePath column will have data like this with semi colon separated values.
ImageID=3215;FilePath=\2016\5\13\test.tif;ImageType=Original;PageNumber=1
The ImageType value needs to be changed to "duplicate" as below for all the rows returned from the query.
ImageID=3215;FilePath=\2016\5\13\test.tif;ImageType=duplicate;PageNumber=1
Any ideas? Is using a cursor good to do this kind of update? The number of rows will be a couple of thousands.
Thank you!
The best idea would be to stop storing multiple values in one column and normalize the database so that you don't run into issues like this.
Barring that, you can try to use REPLACE(), but you need to be very careful that you don't inadvertently change parts of the string that happen to match with your string.
REPLACE(ImagePath, ';ImageType=Original;', ';ImagetType=Duplicate;')
might work, but if that attribute can appear at the end of the string (without a trailing semicolon) then it might fail. It could also fail if there is a space in between the "=" and the attribute/value in some cases. It could also fail if it might be the first attribute without a leading semicolon. There might be some other possible failure cases as well - which is why this isn't how you should be storing your data.
Here is a try:
declare #s varchar(max) = 'ImageID=3215;FilePath=\2016\5\13\test.tif;ImageType=original;PageNumber=1'
select substring(#s, 0, charindex('imagetype=', #s)) + 'ImageType=duplicate' +
substring(#s, charindex(';', #s, charindex('imagetype=',#s)), len(#s))
http://rextester.com/edit/AVQO58898
Description: take everything till imagetype= and add ImageType=duplicate to it and add everything from first semicolon that occurs afterimagetype= till the end.
Use REPLACE
UPDATE i
SET i.ImagePath = REPLACE(i.ImagePath, ';ImageType=Original;', ';ImageType=duplicate;')
From tblCase c WITH (NOLOCK)
inner join tblName n WITH (NOLOCK) on c.CaseID = n.CaseID
inner join tblImage i WITH (NOLOCK) on n.NameID = i.NameID
where n.NameCode = '70'

SQL Query Remove Part of Path/Null

So I am new the whole SQL Query business but I need some help with two issues. My goal is to have anything in the Column "EnvironmentName" that has the word "Database" in Column "NodeName" to be displayed in the query results. I did this with
FROM [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con]
WHERE NodeName = 'Database'
ORDER BY EnvironmentName asc
WHERE NodePath
Results of Query:
I am able to get my query results but would like to remove the rows with NULL. I have tried to use "IS NOT NULL" but SQL Server Management Studio labeles this as "incorrect syntax."
What I have tried:
FROM [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con]
WHERE NodeName = 'Database'
ORDER BY EnvironmentName asc IS NOT NULL
WHERE NodePath
Thank you in advance!
Your query is pretty close..
1: You have to specify a specific column to not be null while using IS NOT NULL.
So modify your query to:
FROM [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con]
WHERE NodeName = 'Database' AND EnvironmentName IS NOT NULL
ORDER BY EnvironmentName asc
WHERE NodePath
2: Check out this article about trimming parts of strings from query results
http://basitaalishan.com/2014/02/23/removing-part-of-string-before-and-after-specific-character-using-transact-sql-string-functions/
Where clause will come first and Then order by statement
Like following way
Select * FROM [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con]
WHERE [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con].[NodeName] = 'Database' AND [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con].[EnvironmentName] IS NOT NULL
ORDER BY [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con].[EnvironmentName] asc
EDIT: I just noticed you removed this from your OP, so feel free to disregard if you took care of that.
I don't think anyone addressed the substring problem yet. There's several ways you could get at this depending on how complex the strings are you have to slice up, but here's how I'd do it
-- Populating some fake data, representative of what you've got
if object_id('tempdb.dbo.#t') is not null drop table #t
create table #t
(
nPath varchar(1000)
)
insert into #t
select '/Database/Mappings/Silver/Birthday' union all
select '/Database/Connections/Blue/Happy'
-- First, get the character index of the first '/' after as many characters the word '/database/' takes up.
-- You could have hard coded this value too. Add 1 to it so that it moves PAST the slash.
;with a as
(
select
ixs = charindex('/', nPath, len('/Database/') + 1),
-- Get everything to the right of what you just determined with all the charindex() stuff
ss = right(nPath, len(nPath) - charindex('/', nPath, len('/Database/') + 1)),
nPath
from #t
)
-- Now just take the left of the now-cleaned-up string from start to the first pipe
select
ixs,
ss,
color = left(ss, charindex('/', ss) -1),
nPath
from a

Format sql column when using select

I have the following query to select record but i wan to format the column on the result set.
SELECT
COALESCE(dbo.tblMitchellLandscapeID.PatchSize,0) as PatchSize,
dbo.tblMitchellLandscape.MitchellLandscapeName
FROM tblMitchellLandscapeID
INNER JOIN dbo.tblMitchellLandscape
ON dbo.tblMitchellLandscapeID.MitchellLandscapeID=dbo.tblMitchellLandscape.MitchellLandscapeID
WHERE AssessmentVersionID = #AssessmentVersionID
"PatchSize" is a decimal value so it stored always like two decimals "15.10". All i trying to format to one decimal when the select statement is executed i wan to populate the result set like "15.1" rather than 15.10.
You can just cast it to the format you want:
SELECT CAST(COALESCE(li.PatchSize, 0) as decimal(5, 1)) as PatchSize,
l.MitchellLandscapeName
FROM tblMitchellLandscapeID li INNER JOIN
dbo.tblMitchellLandscape l
ON li.MitchellLandscapeID = l.MitchellLandscapeID
WHERE AssessmentVersionID = #AssessmentVersionID;
Notice the query is also easier to read (and write) if you use table aliases.

I need to remove leading zeros after a decimal point

this is my first time posting here and I am a basic SQL user and need help.
I have a varchar column that stores data like below:
Year.Docid
2007.000000001
2007.000000002
2007.000000003
2007.000000004
2007.000000005
2007.000000006
I need to join this data to another table that does not have all the zeros after the decimal, can someone please show me how to get the data to look like below:
Year Docid
2007.1
2007.2
2007.3
2007.4
2007.5
2007.6
I am using MICROSOFT SQL SERVER 2012
If the format is fixed, i.e. YYYY.NNNNNNNNN, you could just get the last 9 characters, convert them to int, convert the result back to varchar and concatenate back to the first 5 characters:
LEFT([Year.Docid], 5) + CAST(CAST(RIGHT([Year.Docid], 9) AS int) AS varchar(10))
However, it would make more sense to store Year and Docid as two separate int columns, in both tables. It is much easier to assemble them just for the output than do this processing every time and join on the results of it.
In SQL Server, assuming both columns are varchar, something like this should do you:
select *
from table_1 t1
join table_2 t2 on t2.docid = left(t2.docid,4)
+ '.'
+ convert(varchar,convert(int,right( t2.docid, len(t2.docid)-5 )))
You should bear in mind that making the one table's column an expression means that for that table/column, the query optimizer cannot use any indexes in the query plan.
This is a bit of work, but accomplishes the task of removing the zeros from the right of the dot:
SELECT SUBSTRING(YearDocid, 0, CHARINDEX('.', yearDocId)) +
REPLACE(SUBSTRING(yearDocId,
CHARINDEX('.', yearDocId),
LEN(yearDocID)),
'0', '')
FROM tab1;
sqlfiddle demo
To turn the long format into the short format:
SELECT LEFT('2007.000000001',5) + CAST(CAST(RIGHT('2007.000000001',LEN('2007.000000001')-5) AS int)AS VARCHAR)
...
To use that in a join:
SELECT
...
FROM
TABLE_1 T1
INNER JOIN TABLE_2 T2
ON LEFT(T1.pk,5) + CAST(CAST(RIGHT(T1.pk,LEN(T1.pk)-5) AS int)AS VARCHAR) = T2.pk
SELECT CONCAT(PARSENAME([Col_Varchar],2),'.',CONVERT(INT,PARSENAME([Col_Varchar],1))) FROM Tbl_sample