Getting error when varchar value used in select query - sql

I have a table named 'TABLE_RELATION'. I want to use some of relation codes to filter values from a select query. But when I am trying using IN operator getting an error Conversion failed when converting the varchar value ''301','302','303','304','305','306','312'' to data type smallint.
RELATION_CODE column is type smallint.
declare #guar_tab varchar(max)
declare #guar_tab_VALUES varchar(max)
select #guar_tab=COALESCE(''+#guar_tab+''',''','''')+convert(varchar(100), RELATION_CODE) from TABLE_RELATION where RELATION_CODE>300 and RELATION_CODE<400
SET #guar_tab_VALUES=(select #guar_tab)+''''+''
SELECT #guar_tab_VALUES
select * from TABLE_RELATION where RELATION_CODE in ( #guar_tab_VALUES)
When I tried '301','302','303','304','305','306','312' instead of #guar_tab_VALUES, it is working fine.
How can I solve this issue?
Any help will be appreciated.

You cannot pass a list of values like this. You are passing in a string with a single value that happens to have a bunch of commas.
One simplish method for your code is to use dynamic SQL:
declare #sql nvarchar(max);
set #sql = '
select *
from TABLE_RELATION
where RELATION_CODE in (#guar_tab_VALUES);
';
set #sql = replace(#sql, '#guar_tab_VALUEs', #guar_tab_VALUEs);
exec sp_executesql #sql;

Looking at your query, but I feel I'm missing something. What's wrong with just:
SELECT *
FROM TABLE_RELATION
WHERE RELATION_CODE > 300 AND RELATION_CODE < 400;
You're creating a delimited list of values from the table TABLE_RELATION, and then returning all those rows. There's literally no point. Based on what we have there's no need for dynamic SQL, or an IN.
We could express what you've written as:
SELECT *
FROM TABLE_RELATION TR
WHERE TR.RELATION_CODE IN (SELECT sq.RELATION_CODE
FROM TABLE_RELATION sq
WHERE sq.RELATION_CODE > 300
AND sq.RELATION_CODE < 400);
--or
SELECT *
FROM TABLE_RELATION TR
WHERE EXISTS (SELECT 1
FROM TABLE_RELATION sq
WHERE sq.RELATION_CODE > 300
AND sq.RELATION_CODE < 400
AND TR.RELATION_CODE = sq.RELATION_CODE);
As you can see, there's no need for the subquery,just put it in the main WHERE.

First of all, it's list of numbers.
So something like this
select * from table1
where col1 in ('1', '2', '3')
can be written as
select * from table1
where col1 IN (1, 2, 3)
But IN accepts a list of values, or a query that returns a list of values.
So just adding 1 string with values just won't do.
F.e. this won't work if col1 is a number.
select * from table1 where col1 IN ('1,2,3')
Because the string '1,2,3' can't be implicitly converted to a number.
Using a query could work
select * from table1
where col1 IN (select n from nums where n between 1 and 9)
If you do want use a variable that contains a list of numbers?
Then using a table variable might be for you.
DECLARE #NumTbl TABLE (n smallint primary key);
INSERT INTO #NumTbl (n)
SELECT DISTINCT RELATION_CODE
FROM TABLE_RELATION
WHERE RELATION_CODE > 300
AND RELATION_CODE < 400;
declare #guar_tab_values varchar(max);
select #guar_tab_values = concat(#guar_tab_values+', ', n) from #NumTbl order by n;
select #guar_tab_values as guar_tab_values;
SELECT *
FROM TABLE_RELATION
WHERE RELATION_CODE IN (select n from #NumTbl);
In your case I would just use those criteria in the WHERE clause.
SELECT *
FROM TABLE_RELATION
WHERE RELATION_CODE > 300
AND RELATION_CODE < 400

Such requirement comes many times in many different scenarios. so why not create generic solution.
We can a create user define function to slit comma separated string and return data in form of table.
Generic User Define Function :
-- FUNCTION TO SPLIT STRINGS.
ALTER FUNCTION [dbo].[SplitString]
( #stringToSplit VARCHAR(MAX) )
RETURNS
#returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN
DECLARE #name NVARCHAR(255)
DECLARE #pos INT
WHILE CHARINDEX(',', #stringToSplit) > 0
BEGIN
SELECT #pos = CHARINDEX(',', #stringToSplit)
SELECT #name = SUBSTRING(#stringToSplit, 1, #pos-1)
INSERT INTO #returnList
SELECT #name
SELECT #stringToSplit = SUBSTRING(#stringToSplit, #pos+1, LEN(#stringToSplit)-#pos)
END
INSERT INTO #returnList
SELECT #stringToSplit
RETURN
END
Call use define function:
declare #guar_tab varchar(max)
declare #guar_tab_VALUES varchar(max)
select #guar_tab=COALESCE(''+#guar_tab+',','')+convert(varchar(100), RELATION_CODE) from TABLE_RELATION where RELATION_CODE>300 and RELATION_CODE<400
select * from TABLE_RELATION where RELATION_CODE in (SELECT[Name] FROM dbo.SplitString( #guar_tab))
I hope this will help you :)

Related

How to compare two multiple values columns in SQLSERVER

I have a column that contains some value like : ;1;3;7;2;
And another column with values like : ;5;2;3;
I need to know if at least one of the number in the second column (5,2 or 3) is contained in the first column.
Of course this is an example, I have to do it for several records.
Do you have an idea ?
Here is my code :
SELECT *
FROM COMPANIES
WHERE F_SKILLS IN F_CONVENTION
Check This.
Using below query you can find all common numbers appeared in both columns.
First Create Function "[SplitLongString]":
create FUNCTION [dbo].[SplitLongString]
(
#DelimitedString VARCHAR(MAX),
#Delimiter VARCHAR(100)
)
RETURNS
#tblArray TABLE
(
ElementID INT IDENTITY(1,1),
Element VARCHAR(1000)
)
AS
BEGIN
DECLARE
#siIndex INT,
#siStart INT,
#siDelSize INT
SET #siDelSize = LEN(#Delimiter)
--loop through source string and add elements to destination table array
WHILE LEN(#DelimitedString) > 0
BEGIN
SET #siIndex = CHARINDEX(#Delimiter, #DelimitedString)
IF #siIndex = 0
BEGIN
INSERT INTO #tblArray VALUES(#DelimitedString)
BREAK
END
ELSE
BEGIN
INSERT INTO #tblArray VALUES(SUBSTRING(#DelimitedString, 1,#siIndex - 1))
SET #siStart = #siIndex + #siDelSize
SET #DelimitedString = SUBSTRING(#DelimitedString, #siStart , LEN(#DelimitedString) - #siStart + 1)
END
END
RETURN
END
after you can cross apply to seprate out commo or semi colon. You will get common element under column element. use these column for your further use.
select A.*,y.Element common_element--,X.Element
from #COMPANIES A
CROSS APPLY SplitLongString(F_SKILLS,';') y
CROSS APPLY SplitLongString(F_CONVENTION,';') X
where x.Element=y.Element and ( X.Element!=' ' or X.Element!= null)
Output :
let us know if you have any query.
You can use default function that is dbo.Split('5;2;3;',',')
if you don't have this function you can create your own
Create Function
CREATE FUNCTION 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
after creating function you can add Condition to your Query
select * from yourTableName tbl where (select * from dbo.SplitString(tbl.YourColumnWithSemicoluns,';')) in (select * from dbo.SplitString('5;2;3;',';'))
If you're using SQL Server 2016, check out the string_split function.
Assuming you're not, you can create a split function as per previous answer.
If this isn't an option you can do it with a CTE, but it is likely to be inefficient if you have a large dataset.
create table test(col1 varchar(100), col2 varchar(100));
insert into test values ('a;b;c', 'c;d;e'),('a;b;c','d;e;f'), ('a;b;c', 'b;a;d')
;WITH SplitSting AS
(
SELECT
col1, col2, LEFT(col1,CHARINDEX(';',col1)-1) AS value
,RIGHT(col1,LEN(col1)-CHARINDEX(';',col1)) AS remainder
FROM test
WHERE col1 IS NOT NULL AND CHARINDEX(';',col1)>0
UNION ALL
SELECT
col1, col2,LEFT(remainder,CHARINDEX(';',remainder)-1)
,RIGHT(remainder,LEN(remainder)-CHARINDEX(';',remainder))
FROM SplitSting
WHERE remainder IS NOT NULL AND CHARINDEX(';',remainder)>0
UNION ALL
SELECT
col1, col2,remainder,null
FROM SplitSting
WHERE remainder IS NOT NULL AND CHARINDEX(';',remainder)=0
)
SELECT distinct col1, col2 FROM SplitSting
where ';'+col2+';' like '%;'+value+';%'
If it's a finite set of just a few numbers, you might be able to get away with something as simple as:
SELECT * FROM companies
WHERE (f_skills LIKE '%;1;%' AND f_convention LIKE '%;1;%')
OR (f_skills LIKE '%;2;%' AND f_convention LIKE '%;2;%')
OR (f_skills LIKE '%;3;%' AND f_convention LIKE '%;3;%')
...
If that doesn't work... Well, looks like some of the other answers on the page may be bit more comprehensive... Almost embarrassingly so. Although, if the numbers are really just 1-9 like the question suggests, I stand by my answer. :) I know it looks a little pitiful in comparison, but, seriously, it just might work! If not, I'd start with the one from Mr. Bhosale.

TSQL Select * with alias

I have a column named "format", which contains rows with strings separated by coma , .
Something like:
-query:
SELECT DISTINCT
[format]
FROM
[mydb].[dbo].[Demand_conditions]
-result:
format <- column's name
,one,two,three, <- row 1
,paper,cardboard,metal, <- row 2
I select all from a function which gets the values between comas, something like:
SELECT * FROM [mydb].[dbo].splitstring(
(SELECT DISTINCT
[format]
FROM
[mydb].[dbo].[Demand_conditions]))
Which gives me the following result:
UPDATED: THE DISPLAYED COLUMN NAME IS "Name" and I guess is just Management Studio saying: "your column has no name". I want (as I show in the next example) , the COLUMN to be called "format". I DON'T WANT A VALUE IN THE 1st ROW.
Name <- No column name
one
two
three
paper
cardboard
metal
I need to give a name to the column of the result above:
format <- Column name
one
two
three
paper
cardboard
metal
The code for the splitstring function:
CREATE FUNCTION [dbo].[splitstring] ( #stringToSplit VARCHAR(MAX) )
RETURNS
#returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN
DECLARE #name NVARCHAR(255)
DECLARE #pos INT
WHILE CHARINDEX(',', #stringToSplit) > 0
BEGIN
SELECT #pos = CHARINDEX(',', #stringToSplit)
SELECT #name = SUBSTRING(#stringToSplit, 1, #pos-1)
INSERT INTO #returnList
SELECT #name
SELECT #stringToSplit = SUBSTRING(#stringToSplit, #pos+1, LEN(#stringToSplit)-#pos)
END
INSERT INTO #returnList
SELECT #stringToSplit
RETURN
END
Your syntax is probably syntactically invalid, because I doubt that the split string function takes a table as an argument. Split string functions usually just take strings. The appropriate method is apply.
You can assign column names in table aliases. I would do this as:
SELECT distinct s.format
FROM [mydb].[dbo].[Demand_conditions] dc CROSS APPLY
([mydb].[dbo].splitstring(dc.[format])
) s(format);
The s(format) names the column being returned by the splitstring() function.
This is what worked for me:
SELECT f.[format] from (
SELECT * FROM [mydb].[dbo].splitstring(
(SELECT DISTINCT
[format]
FROM
[mydb].[dbo].[Demand_conditions])) ) f([format])
This should work.
SELECT * FROM [mydb].[dbo].splitstring(
(
SELECT 'format'
UNION
SELECT DISTINCT
[format]
FROM
[mydb].[dbo].[Demand_conditions]))

To find a substring matching separated by commas

I have a table say "user"which is having a col "access" having multi values separated by comma.
and i have another table " codes" which has a column "SCRCODES" having some user codes as single valued.
so i need to check whether the multi values in the col "access" of the table "user" is having any of the values present in the "SCRCODES" col of the table "codes"
someone please advise on this.
Thanks
i think this will help you:
ALTER FUNCTION [dbo].[Split]
(
#RowData NVARCHAR(MAX) ,
#SplitOn NVARCHAR(5)
)
RETURNS #ReturnValue TABLE ( Data NVARCHAR(MAX) )
AS
BEGIN
DECLARE #Counter INT
SET #Counter = 1
WHILE ( CHARINDEX(#SplitOn, #RowData) > 0 )
BEGIN
INSERT INTO #ReturnValue
( data
)
SELECT Data = LTRIM(RTRIM(SUBSTRING(#RowData, 1,
CHARINDEX(#SplitOn,
#RowData) - 1)))
SET #RowData = SUBSTRING(#RowData,
CHARINDEX(#SplitOn, #RowData) + 1,
LEN(#RowData))
SET #Counter = #Counter + 1
END
INSERT INTO #ReturnValue
( data )
SELECT Data = LTRIM(RTRIM(#RowData))
RETURN
END;
GO
DECLARE #str VARCHAR(MAX)
SET #str = select access from users where oid = "1"
SELECT *
FROM codes c, users u where c.SCRCODES in dbo.Split(#str, ',')
I assume that your sercodes does not contain comma.
You can do something like this:
select sercodes from codes
inner join users
on user.codeid = codes.codeid
where charindex(sercodes + ',', access) > 0 or charindex(',' + sercodes , access) > 0
The idea is that access will be stored like this way "read, write, execute". So, it will be either end with comma or start with comma and part of the string..
Please let me know whether it is working. You can give actual table data and design to get more accurate query.

Dynamically Create tables and Insert into it from another table with CSV values

Have a Table with the CSV Values in the columns as below
ID Name text
1 SID,DOB 123,12/01/1990
2 City,State,Zip NewYork,NewYork,01234
3 SID,DOB 456,12/21/1990
What is need to get is 2 tables in this scenario as out put with the corresponding values
ID SID DOB
1 123 12/01/1990
3 456 12/21/1990
ID City State Zip
2 NewYork NewYork 01234
Is there any way of achieving it using a Cursor or any other method in SQL server?
There are several ways that this can be done. One way that I would suggest would be to split the data from the comma separated list into multiple rows.
Since you are using SQL Server, you could implement a recursive CTE to split the data, then apply a PIVOT function to create the columns that you want.
;with cte (id, NameItem, Name, textItem, text) as
(
select id,
cast(left(Name, charindex(',',Name+',')-1) as varchar(50)) NameItem,
stuff(Name, 1, charindex(',',Name+','), '') Name,
cast(left(text, charindex(',',text+',')-1) as varchar(50)) textItem,
stuff(text, 1, charindex(',',text+','), '') text
from yt
union all
select id,
cast(left(Name, charindex(',',Name+',')-1) as varchar(50)) NameItem,
stuff(Name, 1, charindex(',',Name+','), '') Name,
cast(left(text, charindex(',',text+',')-1) as varchar(50)) textItem,
stuff(text, 1, charindex(',',text+','), '') text
from cte
where Name > ''
and text > ''
)
select id, SID, DOB
into table1
from
(
select id, nameitem, textitem
from cte
where nameitem in ('SID', 'DOB')
) d
pivot
(
max(textitem)
for nameitem in (SID, DOB)
) piv;
See SQL Fiddle with Demo. The recursive version will work great but if you have a large dataset, you could have some performance issues so you could also use a user defined function to split the data:
create FUNCTION [dbo].[Split](#String1 varchar(MAX), #String2 varchar(MAX), #Delimiter char(1))
returns #temptable TABLE (colName varchar(MAX), colValue varchar(max))
as
begin
declare #idx1 int
declare #slice1 varchar(8000)
declare #idx2 int
declare #slice2 varchar(8000)
select #idx1 = 1
if len(#String1)<1 or #String1 is null return
while #idx1 != 0
begin
set #idx1 = charindex(#Delimiter,#String1)
set #idx2 = charindex(#Delimiter,#String2)
if #idx1 !=0
begin
set #slice1 = left(#String1,#idx1 - 1)
set #slice2 = left(#String2,#idx2 - 1)
end
else
begin
set #slice1 = #String1
set #slice2 = #String2
end
if(len(#slice1)>0)
insert into #temptable(colName, colValue) values(#slice1, #slice2)
set #String1 = right(#String1,len(#String1) - #idx1)
set #String2 = right(#String2,len(#String2) - #idx2)
if len(#String1) = 0 break
end
return
end;
Then you can use a CROSS APPLY to get the result for each row:
select id, SID, DOB
into table1
from
(
select t.id,
c.colname,
c.colvalue
from yt t
cross apply dbo.split(t.name, t.text, ',') c
where c.colname in ('SID', 'DOB')
) src
pivot
(
max(colvalue)
for colname in (SID, DOB)
) piv;
See SQL Fiddle with Demo
You'd need to approach this as a multi-step ETL project. I'd probably start with exporting the two types of rows into a couple staging tables. So, for example:
select * from yourtable /* rows that start with a number */
where substring(text,1,1) in
('0','1','2','3','4','5','6','7','8','9')
select * from yourtable /* rows that don't start with a number */
where substring(text,1,1)
not in ('0','1','2','3','4','5','6','7','8','9')
/* or simply this to follow your example explicitly */
select * from yourtable where name like 'sid%'
select * from yourtable where name like 'city%'
Once you get the two types separated then you can split them out with one of the already written split functions found readily out on the interweb.
Aaron Bertrand (who is on here often) has written up a great post on the variety of ways to split comma delimted strings using SQL. Each of the methods are compared and contrasted here.
http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings
If your row count is minimal (under 50k let's say) and it's going to be a one time operation than pick the easiest way and don't worry too much about all the performance numbers.
If you have a ton of rows or this is an ETL process that will run all the time then you'll really want to pay attention to that stuff.
A simple solution using cursors to build temporary tables. This has the limitation of making all columns VARCHAR and would be slow for large amounts of data.
--** Set up example data
DECLARE #Source TABLE (ID INT, Name VARCHAR(50), [text] VARCHAR(200));
INSERT INTO #Source
(ID, Name, [text])
VALUES (1, 'SID,DOB', '123,12/01/1990')
, (2, 'City,State,Zip', 'NewYork,NewYork,01234')
, (3, 'SID,DOB', '456,12/21/1990');
--** Declare variables
DECLARE #Name VARCHAR(200) = '';
DECLARE #Text VARCHAR(1000) = '';
DECLARE #SQL VARCHAR(MAX);
--** Set up cursor for the tables
DECLARE cursor_table CURSOR FAST_FORWARD READ_ONLY FOR
SELECT s.Name
FROM #Source AS s
GROUP BY Name;
OPEN cursor_table
FETCH NEXT FROM cursor_table INTO #Name;
WHILE ##FETCH_STATUS = 0
BEGIN
--** Dynamically create a temp table with the specified columns
SET #SQL = 'CREATE TABLE ##Table (' + REPLACE(#Name, ',', ' VARCHAR(50),') + ' VARCHAR(50));';
EXEC(#SQL);
--** Set up cursor to insert the rows
DECLARE row_cursor CURSOR FAST_FORWARD READ_ONLY FOR
SELECT s.Text
FROM #Source AS s
WHERE Name = #Name;
OPEN row_cursor;
FETCH NEXT FROM row_cursor INTO #Text;
WHILE ##FETCH_STATUS = 0
BEGIN
--** Dynamically insert the row
SELECT #SQL = 'INSERT INTO ##Table VALUES (''' + REPLACE(#Text, ',', ''',''') + ''');';
EXEC(#SQL);
FETCH NEXT FROM row_cursor INTO #Text;
END
--** Display the table
SELECT *
FROM ##Table;
--** Housekeeping
CLOSE row_cursor;
DEALLOCATE row_cursor;
DROP TABLE ##Table;
FETCH NEXT FROM cursor_table INTO #Name;
END
CLOSE cursor_table;
DEALLOCATE cursor_table;

How can I introduce multiple conditions in LIKE operator?

I want to write an SQL statement like below:
select * from tbl where col like ('ABC%','XYZ%','PQR%');
I know it can be done using OR. But I want to know is there any better solution.
This is a good use of a temporary table.
CREATE TEMPORARY TABLE patterns (
pattern VARCHAR(20)
);
INSERT INTO patterns VALUES ('ABC%'), ('XYZ%'), ('PQR%');
SELECT t.* FROM tbl t JOIN patterns p ON (t.col LIKE p.pattern);
In the example patterns, there's no way col could match more than one pattern, so you can be sure you'll see each row of tbl at most once in the result. But if your patterns are such that col could match more than one, you should use the DISTINCT query modifier.
SELECT DISTINCT t.* FROM tbl t JOIN patterns p ON (t.col LIKE p.pattern);
Oracle 10g has functions that allow the use of POSIX-compliant regular expressions in SQL:
REGEXP_LIKE
REGEXP_REPLACE
REGEXP_INSTR
REGEXP_SUBSTR
See the Oracle Database SQL Reference for syntax details on this functions.
Take a look at Regular expressions in Perl with examples.
Code :
select * from tbl where regexp_like(col, '^(ABC|XYZ|PQR)');
Here is an alternative way:
select * from tbl where col like 'ABC%'
union
select * from tbl where col like 'XYZ%'
union
select * from tbl where col like 'PQR%';
Here is the test code to verify:
create table tbl (col varchar(255));
insert into tbl (col) values ('ABCDEFG'), ('HIJKLMNO'), ('PQRSTUVW'), ('XYZ');
select * from tbl where col like 'ABC%'
union
select * from tbl where col like 'XYZ%'
union
select * from tbl where col like 'PQR%';
+----------+
| col |
+----------+
| ABCDEFG |
| XYZ |
| PQRSTUVW |
+----------+
3 rows in set (0.00 sec)
select * from tbl where col like 'ABC%'
or col like 'XYZ%'
or col like 'PQR%';
This works in toad and powerbuilder. Don't know about the rest
This might help:
select * from tbl where col like '[ABC-XYZ-PQR]%'
I've used this in SQL Server 2005 and it worked.
I also had the same requirement where I didn't have choice to pass like operator multiple times by either doing an OR or writing union query.
This worked for me in Oracle 11g:
REGEXP_LIKE (column, 'ABC.*|XYZ.*|PQR.*');
Even u can try this
Function
CREATE 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
Query
select * from my_table inner join (select value from fn_split('ABC,MOP',','))
as split_table on my_table.column_name like '%'+split_table.value+'%';
If your parameter value is not fixed or your value can be null based on business you can try the following approach.
DECLARE #DrugClassstring VARCHAR(MAX);
SET #DrugClassstring = 'C3,C2'; -- You can pass null also
---------------------------------------------
IF #DrugClassstring IS NULL
SET #DrugClassstring = 'C3,C2,C4,C5,RX,OT'; -- If null you can set your all conditional case that will return for all
SELECT dn.drugclass_FK , dn.cdrugname
FROM drugname AS dn
INNER JOIN dbo.SplitString(#DrugClassstring, ',') class ON dn.drugclass_FK = class.[Name] -- SplitString is a a function
SplitString function
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
ALTER FUNCTION [dbo].[SplitString](#stringToSplit VARCHAR(MAX),
#delimeter CHAR(1) = ',')
RETURNS #returnList TABLE([Name] [NVARCHAR](500))
AS
BEGIN
--It's use in report sql, before any change concern to everyone
DECLARE #name NVARCHAR(255);
DECLARE #pos INT;
WHILE CHARINDEX(#delimeter, #stringToSplit) > 0
BEGIN
SELECT #pos = CHARINDEX(#delimeter, #stringToSplit);
SELECT #name = SUBSTRING(#stringToSplit, 1, #pos-1);
INSERT INTO #returnList
SELECT #name;
SELECT #stringToSplit = SUBSTRING(#stringToSplit, #pos+1, LEN(#stringToSplit)-#pos);
END;
INSERT INTO #returnList
SELECT #stringToSplit;
RETURN;
END;
I had to add all to Asaph's answer to make it work.
select * from tbl where col like 'ABC%'
union all
select * from tbl where col like 'XYZ%'
union all
select * from tbl where col like 'PQR%';
SELECT *
From tbl
WHERE col
LIKE '[0-9,a-z]%';
simply use this condition of like in sql and you will get your desired answer