How to use CASE WHEN in determining special characters? - sql-server

I'm trying to create a code that will do different update to a specific column based on a set of critierias.
I have a FirstName in the Customer records. Now I need to update the FirstName depending on the data I have in my title.
The logic should go like this...
UPDATE Customer
SET FirstName = If TITLE contains special characters
THEN set firstname to blank
ELSE
SET it to FirstName
From Customer c
INNER JOIN CustomerList cl
on c.customerid = cl.customerid
I'm having troubles doing the logic for the special characters.
I'm not sure whether to use a CASE within a CASE or an IF and CASE statement.
I am able to identify special characters using this code:
SELECT title FROM Customer where LTRIM(RTRIM(title)) NOT LIKE '%[`'' -''|-~.,-#!#$^&*()<>:;''"_+\/=?0-9]%'
I tried to incorporate this into my CASE but I'm getting a syntax error.
Any suggestions on the best way to solve this?
So far my code is like this...
SELECT ID, CASE LTRIM(RTRIM(title))
WHEN Title NOT LIKE '%[`'' -''|-~.,-#!#$^&*()<>:;''"_+\/=?0-9]%' AND RTRIM(LTRIM(title)) NOT IN ('MR', 'MS', 'MRS', 'Miss', 'MSTR', 'MR.', 'MS.', 'MRS.', 'CHD', 'CHIL', 'CHLD', 'DR', 'DR.', 'MAST',''))
THEN title
END
FROM customer

Possible this be helpful for you -
SELECT ID,
CASE
WHEN LTRIM(RTRIM(title)) NOT LIKE '%[`'' -''|-~.,-#!#$^&*()<>:;''"_+\/=?0-9]%'
AND RTRIM(LTRIM(title)) NOT IN ('MR', 'MS', 'MRS', 'Miss', 'MSTR', 'MR.', 'MS.', 'MRS.', 'CHD', 'CHIL', 'CHLD', 'DR', 'DR.', 'MAST','')
THEN title
END
FROM customer
Update:
DECLARE #temp TABLE (title NVARCHAR(50))
INSERT INTO #temp (title)
VALUES ('~test1'), ('MR test'), ('is ok')
SELECT t.*
FROM #temp t
WHERE NOT EXISTS(
SELECT 1
FROM (VALUES
('MR'), ('MS'), ('MRS'),
('Miss'), ('MSTR'), ('MR.'),
('MS.'), ('MRS.'), ('CHD'),
('CHIL'), ('CHLD'), ('DR'),
('DR.'), ('MAST')
) c(t2)
WHERE LTRIM(RTRIM(title)) LIKE '%' + t2 + '%'
)
AND LTRIM(RTRIM(title)) NOT LIKE '%[`'' -''|-~.,-#!#$^&*()<>:;''"_+\/=?0-9]%'

Assuming any character that is not a space or a letter is considered special
UPDATE c
SET FirstName =
case when replace(Title, ' ', '') like '%[^a-z]%'
THEN ''
ELSE FirstName
end
FROM Customer c
INNER JOIN CustomerList cl
on c.customerid = cl.customerid

Related

TSQL Distinct List of departments based on current user

I couldn't even think of how to phrase this properly for the title.
I have an SSRS report with a multi-valued parameter called Department.
If the user IS IN Department A..We want to default to all departments EXCEPT department A
If the user IS NOT IN Department A..We want to default to only their department
Department A will never be in the parameter list but being a member of department A impacts what you will see.
I know that I could resolve this with an ALL parameter option, but I would prefer the only parameter values to be valid department names
My parameter is populated with two datasets.
The first dataset has three options for valid departments: EUR, REM, LIFA
The second dataset only determines the current user's department and would populate the default. IF the current user's department is CS we want to select the other three departments as the default. If their department <> CS we want to default to only their department.
I thought the code below would work but the concatenated string is not an option in the first dataset so it cannot be the default option
SELECT DISTINCT
CASE
WHEN EmployeePracticeArea = 'CS'
THEN 'EUR, LIFA, REM'
ELSE EmployeePracticeArea
END AS 'EmployeePracticeArea'
FROM DimEmployee
WHERE
(EmployeePracticeArea <> '')
AND (UserLogin = #CurrentUser)
The problem with the case statement is that it tries to set a default value of EUR, LIFA, REM. This string does not exist in the 'options' list of values. The options are the three seperate strings EUR, LIFA, REM.
Case statements cannot return multiple values so I need to evaluate the current user's department and then return a list without it
Here is something which will generate the dataset for you
IF OBJECT_ID('tempdb..#TestData') IS NOT NULL
DROP TABLE #TestData;
WITH Data (EmployeePracticeArea) AS (
SELECT 'LIFA'
UNION
SELECT 'REM'
UNION
SELECT 'EUR'
UNION
SELECT 'CS'
)
SELECT * INTO #TestData FROM Data ;
The end result is like this:
User1 in the LIFA department has his parameter defaulted to just LIFA
User2 in the CS department has his parameter defaulted to EUR, LIFA, REM
DECLARE #t TABLE(Dept varchar(4))
DECLARE #CurrentUserDept varchar(4) = (SELECT EmployeePracticeArea FROM dimEmployee WHERE UserLogin = #CurrentUser)
IF #CurrentUserDept = 'CS'
BEGIN
INSERT INTO #t VALUES ('EUR'), ('LIFA'), ('REM')
END
ELSE
BEGIN
INSERT INTO #t SELECT #CurrentUserDept
END
SELECT * FROM #t

SQL Server : Select without some word

I have a procedure like this;
SET #Oldname = (SELECT name
FROM [Marketing].[dbo].[_Users]
WHERE ID = #MID);
Everything is okay but some members got xxx, xxx_A1,xxx_A2,xxx_A3, while selecting these members I want to select without _A1 , _A2 , A_30
How can I select it?
Try reversing string, find first index of _ and apply substring:
DECLARE #s NVARCHAR(MAX) = 'John_Smith_234'
DECLARE #t TABLE ( Name NVARCHAR(50) )
INSERT INTO #t
VALUES ( 'John_Smith_234' ),
( 'Michael_Jordan' ),
( 'Honore_De_Balzak_234' )
SELECT SUBSTRING(Name, 1, LEN(Name) - CHARINDEX('_', REVERSE(Name))) AS Name
FROM #t
Output:
Name
John_Smith
Michael
Honore_De_Balzak
try this
select left(name, len(name)-charindex('_', reverse(name))) name
from whatever
Assure that you add a '%' sign to your #MID Variable, looking like 'xxx%'
Than SELECT with LIKE instead of = :
SET #Oldname = (SELECT name From [Marketing].[dbo].[_Users] Where ID LIKE #MID);
I think you may also add the '%' sign in qour query (haven't tried):
SET #Oldname = (SELECT name From [Marketing].[dbo].[_Users] Where ID LIKE #MID+'%');

Query so much slower than stored procedure?

I have created a query which performs with aprox 2 seconds with top 100. If i create a stored procedure of this exact query it takes 12-13 seconds to run.
Why would that be?
Elements table count = 2309015 (with userid specified = 326969)
Matches table count = 1290 (with userid specified = 498)
sites table count = 71 (with userid specified = 9)
code
with search (elementid, siteid, title, description, site, link, addeddate)
as
(
select top(#top)
elementid,
elements.siteid, title, elements.description,
site =
case sites.description
when '' then sites.name
when null then sites.name
else sites.name + ' (' + sites.description + ')'
end,
elements.link,
elements.addeddate
from elements
left join sites on elements.siteid = sites.siteid
where title like #search and sites.userid = #userid
order by addeddate desc
)
select search.*, isnull(matches.elementid,0) as ismatch
from search
left join matches on matches.elementid = search.elementid
When you create SP it is compiled and stored and when the SP has parameters, by which you filter your result, the optimizer don't know which value you will pass on execution, then he treat as 33% selection and by this creates plan. When you execute query, the values are provided and optimizer create the execution plan depended on this values. I sure, the the plans are different.
Without code, I can only guess. When writing a sample query, you first have a constant where clause and second a cache. The stored procedure has no chance of either caching or optimizing the query plan based on a constant in the where clause.
I can suggest two ways to try
First one, write your sp like this:
create procedure sp_search
(
#top int,
#search nvarchar(max),
#userid int
)
as
begin
declare #p_top int, #p_search nvarchar(max), #p_userid int
select #p_top = #top, #p_search = #search, #p_userid = #userid
with search (elementid, siteid, title, description, site, link, addeddate)
as
(
select top(#p_top)
elementid,
elements.siteid, title, elements.description,
site =
case sites.description
when '' then sites.name
when null then sites.name
else sites.name + ' (' + sites.description + ')'
end,
elements.link,
elements.addeddate
from elements
left join sites on elements.siteid = sites.siteid
where title like #p_search and sites.userid = #p_userid
order by addeddate desc
)
select search.*, isnull(matches.elementid,0) as ismatch
from search
left join matches on matches.elementid = search.elementid
end
Second one, use inline table function
create function sf_search
(
#top int,
#search nvarchar(max),
#userid int
)
returns table
as
return
(
with search (elementid, siteid, title, description, site, link, addeddate)
as
(
select top(#top)
elementid,
elements.siteid, title, elements.description,
site =
case sites.description
when '' then sites.name
when null then sites.name
else sites.name + ' (' + sites.description + ')'
end,
elements.link,
elements.addeddate
from elements
left join sites on elements.siteid = sites.siteid
where title like #search and sites.userid = #userid
order by addeddate desc
)
select search.*, isnull(matches.elementid,0) as ismatch
from search
left join matches on matches.elementid = search.elementid
)
There is a similar question here
The problem was the stored proc declaration SET ANSI_NULLS OFF

Adding Dyanmic In() Conditions in Sql Server

Facing problem for generating SQL Server Query
In the Following query dynamic conditions are added to check whether value is null or not
Select *
From tblEmployees
where EmployeeName = Case
When #EmployeeName Is Not Null
Then #EmployeeName
Else EmployeeName
End
But I need to add IN () Conditions and the parameter with in the IN () could be null or blank also ,if the parameter /string which is passed to the IN condition is blank then i donot want to add that condition in the query.
So how can i Achieve this.A helping hand will be very useful for me.
Thanks and Regards,
D.Mahesh
Depending on value of your parameter (blank of not), you can create SQL string accordingly.
DECLARE #sqlCommand VARCHAR(1000)
IF(ISNULL(#YourParameter,'')='')
#sqlCommand = 'your query goes here'
ELSE
#sqlCommand = 'your query goes here'
and then, run it using dynamic query execution
EXEC (#sqlCommand)
If not dynamic query then,
SELECT ....
FROM ....
WHERE CASE WHEN ISNULL(#YourParameter,'')='' THEN '' ELSE EmployeeName END IN (ISNULL(#YourParameter,''))
See if this works...
I think the Dynamic query is the best solution, however you could put the "IS NULL" and "IS BLANK" condition in OR with your IN clause.
Something like that
Select *
From tblEmployees
where #EmployeeName is null or EmployeeName in (#EmployeeName)
When #EmployeeName is null, your IN clause will be ignored
If i get this right you have #EmployeeName = 'Name1,Name2,Name3' and you want to get the employees that is named Name1 or Name2 or Name3, also the variable #EmployeeName can be null or contain an empty string.
Instead of using IN you can split the string #EmployeeName on , and store it in a table variable or temporary table. Then you can use that table in a join against tblEmployees to get the rows you need.
There are a lot of posts in S.O. about how to split a string. Here is one recent variant.
Group by sql query on comma joined column
This will work for SQL Server 2005 or later.
declare #EmployeeName varchar(100) = 'Name2,Name3,Name5'
-- Null or empty will have a comma
set #EmployeeName = coalesce(#EmployeeName, '') + ','
-- cteNames splits the string to rows
;with cteNames
as
(
select
left(#EmployeeName, charindex(',', #EmployeeName)-1) as Name,
right(#EmployeeName, len(#EmployeeName)-charindex(',', #EmployeeName)) as EmployeeName
union all
select
left(EmployeeName, charindex(',', EmployeeName)-1) as Name,
right(EmployeeName, len(EmployeeName)-charindex(',', EmployeeName)) as EmployeeName
from cteNames
where charindex(',', EmployeeName) > 1
)
select E.*
from tblEmployees as E
inner join cteNames as N
on E.Name = N.Name or
#EmployeeName = ','
-- #EmployeeName = ',' will give you all names when #EmployeeName is null of empty

How do I check if a SQL Server text column is empty?

I am using SQL Server 2005. I have a table with a text column and I have many rows in the table where the value of this column is not null, but it is empty. Trying to compare against '' yields this response:
The data types text and varchar are incompatible in the not equal to operator.
Is there a special function to determine whether the value of a text column is not null but empty?
where datalength(mytextfield)=0
ISNULL(
case textcolum1
WHEN '' THEN NULL
ELSE textcolum1
END
,textcolum2) textcolum1
Actually, you just have to use the LIKE operator.
SELECT * FROM mytable WHERE mytextfield LIKE ''
To get only empty values (and not null values):
SELECT * FROM myTable WHERE myColumn = ''
To get both null and empty values:
SELECT * FROM myTable WHERE myColumn IS NULL OR myColumn = ''
To get only null values:
SELECT * FROM myTable WHERE myColumn IS NULL
To get values other than null and empty:
SELECT * FROM myTable WHERE myColumn <> ''
And remember use LIKE phrases only when necessary because they will degrade performance compared to other types of searches.
SELECT * FROM TABLE
WHERE ISNULL(FIELD, '')=''
Use the IS NULL operator:
Select * from tb_Employee where ename is null
I know this post is ancient but, I found it useful.
It didn't resolve my issue of returning the record with a non empty text field so I thought I would add my solution.
This is the where clause that worked for me.
WHERE xyz LIKE CAST('% %' as text)
Use DATALENGTH method, for example:
SELECT length = DATALENGTH(myField)
FROM myTABLE
Instead of using isnull use a case, because of performance it is better the case.
case when campo is null then '' else campo end
In your issue you need to do this:
case when campo is null then '' else
case when len(campo) = 0 then '' else campo en
end
Code like this:
create table #tabla(
id int,
campo varchar(10)
)
insert into #tabla
values(1,null)
insert into #tabla
values(2,'')
insert into #tabla
values(3,null)
insert into #tabla
values(4,'dato4')
insert into #tabla
values(5,'dato5')
select id, case when campo is null then 'DATA NULL' else
case when len(campo) = 0 then 'DATA EMPTY' else campo end
end
from #tabla
drop table #tabla
I would test against SUBSTRING(textColumn, 0, 1)
Are null and an empty string equivalent? If they are, I would include logic in my application (or maybe a trigger if the app is "out-of-the-box"?) to force the field to be either null or '', but not the other. If you went with '', then you could set the column to NOT NULL as well. Just a data-cleanliness thing.
I wanted to have a predefined text("No Labs Available") to be displayed if the value was null or empty and my friend helped me with this:
StrengthInfo = CASE WHEN ((SELECT COUNT(UnitsOrdered) FROM [Data_Sub_orders].[dbo].[Snappy_Orders_Sub] WHERE IdPatient = #PatientId and IdDrugService = 226)> 0)
THEN cast((S.UnitsOrdered) as varchar(50))
ELSE 'No Labs Available'
END
You have to do both:
SELECT * FROM Table WHERE Text IS NULL or Text LIKE ''
I know there are plenty answers with alternatives to this problem, but I just would like to put together what I found as the best solution by #Eric Z Beard & #Tim Cooper with #Enrique Garcia & #Uli Köhler.
If needed to deal with the fact that space-only could be the same as empty in your use-case scenario, because the query below will return 1, not 0.
SELECT datalength(' ')
Therefore, I would go for something like:
SELECT datalength(RTRIM(LTRIM(ISNULL([TextColumn], ''))))
try this:
select * from mytable where convert(varchar, mycolumn) = ''
i hope help u!
DECLARE #temp as nvarchar(20)
SET #temp = NULL
--SET #temp = ''
--SET #temp = 'Test'
SELECT IIF(ISNULL(#temp,'')='','[Empty]',#temp)
It will do two things:
Null check and string null check
Replace empty value to default value eg NA.
SELECT coalesce(NULLIF(column_name,''),'NA') as 'desired_name') from table;

Resources