remove numeric values in data using sql - sql

my data is :
Id Case ID#
1. QCCR1A105369, QCCR1A104986 ,QCCR1A103717
2. QCIM1A106902,4613410733 QCIM1A106902; 4613344523 QCIM1A105842; 4614004212 QCIM1A106580; 4614060189 QCIM1A106676
3. QCCR1D93616, QCCR1D92488, QCCR1D58461
4. QCCR1B40216 .... ,QCCR1B39080, QCCR1B40216, QCCR1B39745, QCCR1B38463 , QCCR1B38618, QCCR1B38619, QCCR1B38620, QCCR1B38621, QCCR1B38622, QCCR1B38465, QCCR1B38623
5. QCCR2A30221 QCCR2A30223 QCCR2A30222 QCIM2A30416
My output will be Id 1,3,4,5. I want only that rows, which have starting value QC not any numeric value. For ID 2 you can see there are some numeric values, please tell me how can I achieve it.

You could use a table valued function to split your value by a delimiter like this:
CREATE FUNCTION [dbo].[Split]
(
#ItemList NVARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #ItemTable TABLE (Item VARCHAR(250))
AS
BEGIN
DECLARE #tempItemList NVARCHAR(MAX)
SET #tempItemList = #ItemList
DECLARE #i INT
DECLARE #Item NVARCHAR(4000)
SET #i = CHARINDEX(#delimiter, #tempItemList)
WHILE (LEN(#tempItemList) > 0)
BEGIN
IF #i = 0
SET #Item = #tempItemList
ELSE
SET #Item = LEFT(#tempItemList, #i - 1)
INSERT INTO #ItemTable(Item) VALUES(#Item)
IF #i = 0
SET #tempItemList = ''
ELSE
SET #tempItemList = RIGHT(#tempItemList, LEN(#tempItemList) - #i)
SET #i = CHARINDEX(#delimiter, #tempItemList)
END
RETURN
END
Then this query returns the expected result:
SELECT t.*
FROM dbo.TableName t
WHERE NOT EXISTS
(
SELECT 1 FROM dbo.Split(t.CaseID, ',') split
WHERE NOT LEFT(LTRIM(split.Item), 2) = 'QC'
OR ISNUMERIC(split.Item) = 1
)
Demo with your sample data. But in general you should avoid multiple values in one column. Instead store it in separate rows in a linked table. That's called database normalization.

Related

how to pass more values for a single parameter in storedprocedure in sql server

MY text:-
CREATE proc usp_delete
#tranid int
as
begin
delete from customer where tranid in(#tranid)
end
Note:- I want to delete records more than 1 records through this stored procedure like:- if I pass 1,2,3,4,5,6 that time all 6 records should be deleted
You can use table-valued parameter for that you need to declare that
CREATE TYPE EntityId AS TABLE
( Id INT )
GO
CREATE PROCEDURE usp_delete
#tranid EntityId READONLY
AS
BEGIN
DELETE c
FROM customer c
JOIN #tranid t ON t.Id=c.tranid
END
For Executing with TVP declare a varible of type and pass it to the stored procedure
DECLARE #entityId EntityId
INSERT INTO #entityId
VALUES(1),(2),(3),(4),(5)
EXEC usp_delete #entityId
In later version of SQL Server you can use STRING_SPLIT to convert a delimited list into individual values and then join to your table using CROSS APPLY.
CREATE PROC usp_delete #tranid VARCHAR(MAX) AS
BEGIN
DELETE c
FROM customer c
CROSS APPLY STRING_SPLIT(#tranid, ',')
WHERE c.tranid = value
END
GO
EXEC usp_delete '2,3,4'
In older version you can write your own table-valued function to convert a delimited string into a result set.
CREATE function [dbo].[delimited_string_to_table] (
#delimiter char(1)
, #string text
)
returns #table table (
seqnbr int not null
, string varchar(255) not null
)
as
begin
declare #pos int
declare #textpos int
declare #chunklen smallint
declare #tmpstr varchar(8000)
declare #leftover varchar(8000)
declare #tmpval varchar(8000)
declare #seq int = 1
set #textpos = 1
set #leftover = ''
while #textpos <= datalength(#string)
begin
set #chunklen = 8000 - datalength(#leftover) / 2
set #tmpstr = #leftover + substring(#string, #textpos, #chunklen)
set #textpos = #textpos + #chunklen
set #pos = charindex(#delimiter, #tmpstr)
while #pos > 0
begin
set #tmpval = ltrim(rtrim(left(#tmpstr, #pos - 1)))
insert #table (seqnbr, string) values(#seq, #tmpval)
set #tmpstr = substring(#tmpstr, #pos + 1, len(#tmpstr))
set #pos = charindex(#delimiter, #tmpstr)
set #seq = #seq + 1
end
set #leftover = #tmpstr
end
if len(rtrim(ltrim(#leftover))) != 0
insert #table(seqnbr, string) values (#seq, ltrim(rtrim(#leftover)))
return
end
GO
Which would change the example to look like this:
CREATE PROC usp_delete #tranid VARCHAR(MAX) AS
BEGIN
DELETE c
FROM customer c
JOIN dbo.delimited_string_to_table(',', #tranid)
ON c.tranid = string
END
GO

Conversion failed when converting the nvarchar value '55100,63622' to data type int

I am passing to a stored procedure values such as '55100,63622', these are placed in a variable #StaffList NVARCHAR(MAX)
Then I try to use these two numbers in a select, then insert them into a temp table. I get the following error: Conversion failed when converting the nvarchar value '55100,63622' to data type int.
INSERT INTO #Staff (StaffId, Forename, Surname)
SELECT AutoID, Forename, Surname
FROM tblUserData WHERE AutoID in (#StaffList)
I am wondering how I can pass the '55100,63622' as a string to the stored procedure, and use in a select statement? Would be better to change the string to OR statements, 'AutoID = 55100 OR AutoID = 6322'
You have to use a split function to split the comma separated values into rows and then use that in the where clause. see the sample below
INSERT INTO #Staff (StaffId, Forename, Surname)
SELECT AutoID, Forename, Surname
FROM tblUserData WHERE AutoID in (select * from dbo.split(#StaffList,','))
split function sample
CREATE FUNCTION dbo.SplitString
(
#Input NVARCHAR(MAX),
#Character CHAR(1)
)
RETURNS #Output TABLE (
Item NVARCHAR(1000)
)
AS
BEGIN
DECLARE #StartIndex INT, #EndIndex INT
SET #StartIndex = 1
IF SUBSTRING(#Input, LEN(#Input) - 1, LEN(#Input)) <> #Character
BEGIN
SET #Input = #Input + #Character
END
WHILE CHARINDEX(#Character, #Input) > 0
BEGIN
SET #EndIndex = CHARINDEX(#Character, #Input)
INSERT INTO #Output(Item)
SELECT SUBSTRING(#Input, #StartIndex, #EndIndex - 1)
SET #Input = SUBSTRING(#Input, #EndIndex + 1, LEN(#Input))
END
RETURN
END
GO
A field with '55100,63622' is a multivaluated field. Your data is not in firts normal form. You should avoid to store several values in a field designed to store just one.
You should to pas two values #staf1, #staf2:
AutoId in ( #staf1, #staf2 )
If you have a variable number of parameters I suggest to you to pass an XML as parameter and join it in your select.
Search about xml parameter or xml join. Some sample:
http://weblogs.asp.net/jongalloway/passing-lists-to-sql-server-2005-with-xml-parameters
Also, SQL Server 2008 and newer, you have table-valued parameters:
https://msdn.microsoft.com/en-us/library/bb510489.aspx
Both structures are intended to store more than one value.
Your in statement around #StaffList should be a table. We have a function called SPLIT that returns a table, so the where clause would look like
... where AutoID in (Select * from dbo.SPLIT(#StaffList,','))
Here is a split function:
CREATE FUNCTION [dbo].[Split]
(
#ItemList VARCHAR(max),
#delimiter CHAR(1)
)
RETURNS #IDTable TABLE (Item VARCHAR(36))
AS
BEGIN
DECLARE #tempItemList VARCHAR(max)
SET #tempItemList = #ItemList
DECLARE #i INT
DECLARE #Item VARCHAR(max)
SET #tempItemList = REPLACE (#tempItemList, ' ', '')
SET #i = CHARINDEX(#delimiter, #tempItemList)
WHILE (LEN(#tempItemList) > 0)
BEGIN
IF #i = 0
SET #Item = #tempItemList
ELSE
SET #Item = LEFT(#tempItemList, #i - 1)
INSERT INTO #IDTable(Item) VALUES(#Item)
IF #i = 0
SET #tempItemList = ''
ELSE
SET #tempItemList = RIGHT(#tempItemList, LEN(#tempItemList) - #i)
SET #i = CHARINDEX(#delimiter, #tempItemList)
END
RETURN
END

case statement in t-sql

I have table similar to:
Create Table #test (Letter varchar(5), Products varchar(30))
Insert into #test (Letter, Products)
Values ('A','B,C,D,E,F'),('B','B,C,D,E,F'),('G','B,C,D,E,F'),('Z','B,C,D,E,F'),('E','B,C,D,E,F')
Is it possible to write a CASE Statement which will check if the list in the 'Products' column contain a letter from 'Letter' column?
Thanks
Here is the query
Select *, Case When (charindex(Letter, Products, 0)>0) Then 'Yes' Else 'No' End AS [Y/N] from #test
I think i managed to do the trick:
CASE WHEN Products LIKE '%'+Letter+'%' THEN 'TRUE' ELSE 'FALSE' END
You could use EXISTS with a split-function:
SELECT Letter, Products,
ContainsLetter = CASE WHEN EXISTS
(
SELECT 1 FROM dbo.Split(t1.Products, ',')s
WHERE s.Item = Letter
)
THEN 'Yes' ELSE 'No' END
FROM #test t1
Demo
Here is the one i'm using on SQL-Server 2005:
CREATE FUNCTION [dbo].[Split]
(
#ItemList NVARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #ItemTable TABLE (Item VARCHAR(250))
AS
BEGIN
DECLARE #tempItemList NVARCHAR(MAX)
SET #tempItemList = #ItemList
DECLARE #i INT
DECLARE #Item NVARCHAR(4000)
SET #i = CHARINDEX(#delimiter, #tempItemList)
WHILE (LEN(#tempItemList) > 0)
BEGIN
IF #i = 0
SET #Item = #tempItemList
ELSE
SET #Item = LEFT(#tempItemList, #i - 1)
INSERT INTO #ItemTable(Item) VALUES(#Item)
IF #i = 0
SET #tempItemList = ''
ELSE
SET #tempItemList = RIGHT(#tempItemList, LEN(#tempItemList) - #i)
SET #i = CHARINDEX(#delimiter, #tempItemList)
END
RETURN
END

Select * from table where column = (any value from a comma delimited string)

The user selects various words from a drop down list and these values get added into a comma delimited string. When passing the string to a stored procedure I want it to select * from a table where that word exists.
Table
id----word
1-----cat
2-----dog
3-----mouse
4-----dog
string that is passed into the stored procedure is cat, dog so returning columns 1, 2 and 4.
Is there a way of doing this in sql server?
Use IN:
SELECT *
FROM your_table
WHERE word IN ('cat', 'dog')
you first need to make a function SplitCSV :
CREATE FUNCTION [dbo].[SplitCSV] (#CSVString VARCHAR(8000), #Delimiter CHAR(1))
RETURNS #temptable TABLE (items VARCHAR(8000))
AS
BEGIN
DECLARE #pos INT;
DECLARE #slice VARCHAR(8000);
SELECT #pos = 1;
IF LEN(#CSVString) < 1 OR #CSVString IS NULL RETURN;
WHILE #pos!= 0
BEGIN
SET #pos = CHARINDEX(#Delimiter,#CSVString);
IF #pos != 0
SET #slice = LEFT(#CSVString, #pos - 1);
ELSE
SET #slice = #CSVString;
IF( LEN(#slice) > 0)
INSERT INTO #temptable(Items) VALUES (#slice);
SET #CSVString = RIGHT(#CSVString, LEN(#CSVString) - #pos);
IF LEN(#CSVString) = 0 BREAK;
END
RETURN
END
GO
then you can use it like :
SELECT *
FROM myTable
WHERE ID IN (
SELECT items FROM [dbo].[SplitCSV]('1,2,3,4,5', ',')
)
SELECT *
FROM Table
WHERE '%,' + Word + ',%' LIKE ',' + #your_csv_param + ','
Extra commas at the begin and end of parameter and column are to prevent search to match cat with catfish for example.
If you want select all animal except mouse , you can use NOT IN
SELECT * FROM
TABLE
WHERE Word Not IN('Mouse')
So you can avoid type many type of animal
CREATE FUNCTION
ALTER FUNCTION [dbo].[fn_Split](#text varchar(8000), #delimiter varchar(20) = ' ')
RETURNS #Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(8000)
)
AS
BEGIN
DECLARE #index int
SET #index = -1
WHILE (LEN(#text) > 0)
BEGIN
SET #index = CHARINDEX(#delimiter , #text)
IF (#index = 0) AND (LEN(#text) > 0)
BEGIN
INSERT INTO #Strings VALUES (#text)
BREAK
END
IF (#index > 1)
BEGIN
INSERT INTO #Strings VALUES (LEFT(#text, #index - 1))
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
ELSE
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
RETURN
END
----
select * from yourtable where column in ( select value from fn_Split(#para1,',')

HOW to convert CSV to record set inside T-SQL?

In my stored procedure I am passing a filter (using "WHERE Column IN" clause) as a parameter. The value of the parameter is given as CSV. What is the best method to convert this CSV in to a record set.
Example:-
SELECT *
FROM Employee
WHERE Name IN ('John','Joe','Jerry','James')
and I need to pass the names as a parameter which is a CSV string like
"John,Joe,Jerry,James"
.
Take a look at Erland Sommarskog's articles. He has in-depth information on the different ways of doing this kind of thing:
Arrays and Lists in SQL Server
Create a split string function
CREATE FUNCTION [dbo].[SplitString]
(
#String VARCHAR(MAX) ,
#Delimiter VARCHAR(10)
)
RETURNS #RetTable TABLE(
String varchar(MAX)
)
AS
BEGIN
DECLARE #i INT ,
#j INT
SELECT #i = 1
WHILE #i <= LEN(#String)
BEGIN
SELECT #j = CHARINDEX(#Delimiter, #String, #i)
IF #j = 0
BEGIN
SELECT #j = LEN(#String) + 1
END
INSERT #RetTable SELECT SUBSTRING(#String, #i, #j - #i)
SELECT #i = #j + LEN(#Delimiter)
END
RETURN
END