OK I have a question to which an answer might be simple but im not sure how to do it:
Question:
How do i use IN with LIKE?
Why Not Duplicate:
Well I know if i have multiple strings i can use OR to check. But this is not the case with what i am trying to do.
Question Explaination:
I have an SP with a parameter #path, now i would like to send multiple paths, separated by delimiter, (to avoid calling sp multiple times). I split the string using a custom function which returns a table with splited values.
Now how would i go about using the values from that splited values table to be used with LIKE operator.
What I have done so far:
declare
#path varchar(max) = 'CompanyRules/Billing/IntegrationServices|CompanyRules/Reports/IntegrationServices',
#default_code varchar(max) = '1'
declare #tempTable TABLE(path varchar(max))
INSERT INTO #tempTable (path)
SELECT split from fn_splitby(#path, '|')
select prg.path, prg.default_code, prmd.optional_property_1, prmd.optional_property_2, prmd.optional_property_3, prmd.optional_property_4, prmd.optional_property_5, prmd.optional_property_6
from pdm_rule_group prg, pdi_rule_master prmd
where prg.path = prmd.path
AND prg.path in (select path from #tempTable)
AND prg.default_code != #default_code
The this will not yield any result.
Possible Solution:
What i though was that i have to loop through the #tempTable and then create separate strings to be used with LIKE. Which im sure is a bad solution, and may have some other solution to it.
Replace this statement
AND prg.path in (select path from #tempTable)
with
AND EXISTS (select 1 from #tempTable where prg.path like "%"+path+"%" )
Just join to the table:
select prg.path, prg.default_code, prmd.optional_property_1, prmd.optional_property_2, prmd.optional_property_3, prmd.optional_property_4, prmd.optional_property_5, prmd.optional_property_6
from
pdm_rule_group prg
inner join
pdi_rule_master prmd
on prg.path = prmd.path
inner join
#tempTable tt
on
prg.path like tt.path
where
prg.default_code != #default_code
Related
I am running a query similar to
DECLARE #VARIABLE NVARCHAR(50) = 'VALUE';
WITH MYCTE_TABLE (Column1,Column2)
AS
SELECT
(ColumnA, Column B
FROM
SomeTable
WHERE
ColumnA = SomeValue)
IF EXISTS(SELECT ColumnZ FROM AnotherTable WHERE Columnz = SomeNumbers)
BEGIN
SELECT * FROM MYCTE_TABLE
END
ELSE
BEGIN
MYSUBQUERY2
END
...
However, I keep getting the following error:
Incorrect syntax near the keyword 'IF'.
Each subquery works well when run independently. It seems the use of a common table expression before the IF EXISTS is causing the issue.
Any help please?
I really doubt, that this is the best approach... You tried to clean and shorten this for brevitiy (thumbs up for this!), but the given information is - maybe - not enough.
You cannot use a CTE in different queries. A CTE is fully inlined as part of the query...
But you could write your values into a table variable like here:
DECLARE #tbl TABLE(Column1 INT, Column2 VARCHAR(100)); --Choose appropriate types
INSERT INTO #tbl
SELECT ColumnA, ColumnB FROM SomeTable WHERE ColumnA=SomeValue;
This table variable can be used in later queries (but in the same job!) like any other table:
SELECT *
FROM SomeTable AS st
INNER JOIN #tbl AS tbl ON ...
... or similiar usages...
Another approach might be this
SELECT Column1,Column2 INTO #SomeTempTable FROM SomeWhere
This will write the result of the SELECT into a temp table (which is session wide).
I'm quite sure, that there might be a better (set-based) approach... Are the two sub-queries identical in their result set's structure? If so, you might use UNION ALL and place your "IF EXISTS" as a WHERE-clause to each sub query.
IF is control flow. WITH is within a query. You can do:
IF EXISTS (SELECT ColumnZ FROM AnotherTable WHERE Columnz=SomeNumbers)
BEGIN
WITH MYCTE_TABLE (Column1,Column2)AS
SELECT (ColumnA, Column B FROM SomeTable WHERE ColumnA=SomeValue)
MYSUBQUERY1
END;
ELSE
BEGIN
WITH MYCTE_TABLE (Column1,Column2)AS
SELECT (ColumnA, Column B FROM SomeTable WHERE ColumnA=SomeValue)
MYSUBQUERY2
END;
Or you could use a temporary table or table variable to store the values.
The answer escapes me...maybe because it is not possible...
Example that works...
SELECT * FROM TABLEA WHERE FIELD1 IN ('aaa','bbb','ccc')
Example that does not work...
Attempt to leverage variable so that I can define the values once in a string of statements
DECLARE #ListValues VARCHAR(50)
SET #ListValues = '''aaa'',''bbb'',''ccc'''
SELECT * FROM TABLEA WHERE FIELD1 IN (#ListValues)
This is is obviously only a small part of the equation and for other reasons...
I cannot leverage a table for the values and change this to a true sub-query
The closest question I could find was this one... but does not cover my requirements obviously...
Storing single quotes in varchar variable SQL Server 2008
Thanks in advance.
You can do this using dynamic SQL:
DECLARE #ListValues VARCHAR(MAX)
,#SQL VARCHAR(MAX)
SELECT #ListValues = '''aaa'',''bbb'',''ccc'''
,#SQL = 'SELECT * FROM TABLEA WHERE FIELD1 IN ('+#ListValues+')'
EXEC (#SQL)
It doesn't work because the IN operator expects a list of items - here strings.
What you're supplying with your #ListValues variable however is a single string - not a list of strings.
What you could do is use a table variable and store your values in it:
DECLARE #ListOfValues TABLE (ItemName VARCHAR(50))
INSERT INTO #ListOfValues(ItemName)
VALUES('aaa'), ('bbb'), ('ccc')
SELECT *
FROM TABLEA
WHERE FIELD1 IN (SELECT ItemName FROM #ListOfValues)
Build your whole SQL query dynamically (say it's stored in a string variable #sql),
and then execute it with EXEC (#sql). Better yet, use the sp_executesql SP
because this approach is more secure (less prone to SQL injection) than EXEC.
See: sp_executesql
The IN operator in SQLServer expect a list of values, your variable is a single string, the query parsed will be different
SELECT * FROM TABLEA WHERE FIELD1 IN ('aaa','bbb','ccc')
SELECT * FROM TABLEA WHERE FIELD1 IN ("'aaa','bbb','ccc'")
Attention: the double quotes are there only for readability, to get the string with single quote in it.
if you know a programming language the first one is like searching in an array, the second is a string.
To store a list in your variable it need to a table
DECLARE #varTable TABLE (field1 varchar())
So that you can use it in your IN
SELECT * FROM TABLEA WHERE FIELD1 IN (SELECT field1 FROM #varTable)
To add values to the table variable use an INSERT statament like usual for tables.
I have a large number to find in a table. But only a little part of it is given to me to find the whole number. I am looking for some new way to find these out without using the like operator. I know it is a simple thing, but I need a new approach.
Value given is: 4213076600
Value to find is: 89013106904213076600
I want to find it in the following query:
SELECT *
FROM table_name
WHERE column_name in (value,value,value)
i have searched the websites for this and came to know about the left() and right() functions but don't know how to arrange them to get the result
You can use CONTAINS more info:
SELECT *
FROM table_name
WHERE CONTAINS(column_name , '"*value*"')
For CONTAINS you need to create a FULL TEXT INDEX on the table.
DECLARE #table table (n varchar(20))
DECLARE #param1 varchar(20)
SET #param1 = '4213076600'
INSERT INTO #table (n)
SELECT '89013106904213076600'
SELECT n
FROM #table
WHERE RIGHT(n, len(#param1)) = #param1
Edit
select *
from table_name
where right(column_name, len(value)) = value
SELECT
*
FROM
table_name
WHERE
CHARINDEX(value1,column_name)>0
OR CHARINDEX(value2,column_name)>0
OR CHARINDEX(value3,column_name)>0
SELECT left(column_name,length_of_value)
FROM table_name
WHERE RIGHT(column_name,length_of_value_given) IN (value,value,value)
That's way it works for IN clause
I am working on a query page where a user selects a value which represents different types, each identified by an ID.
The problem is selecting these IDs from the data base using the WHERE IN method.
This is my SQL statement
SELECT M.REG_NO, T.TYPE_ID
FROM MAIN AS M
INNER JOIN CLASSIFICATION AS C
ON M.REG_NO = C.REG_NO
INNER JOIN TYPE AS T
ON T.TYPE_ID = C.TYPE_ID
WHERE T.TYPE_ID IN (#Types)
it will work for one single value, eg. 46, but NOT if the value is in brackets, eg. (46) or ('46'), the way it should be for the IN.
I am using visual studio which is auto generating the method to access the table adapter to get the values so I think I HAVE to do this through SQL.
I am passing a string, eg. Types = "46,267,2010" , into the adapter method which passes the string into the #Types in the SQL statement.
Any help would be great. Thanks!
This is a pretty common problem -- not sure why TSQL hasn't dealt with it yet. Anyway, the solution I've found works best for me is to convert the variable to a table, and then you can use IN() on it just fine.
Starting with the function:
CREATE Function [dbo].[ParseStringList] (#StringArray nvarchar(max) )
Returns #tbl_string Table (ParsedString nvarchar(max)) As
BEGIN
DECLARE #end Int,
#start Int
SET #stringArray = #StringArray + ','
SET #start=1
SET #end=1
WHILE #end<Len(#StringArray)
BEGIN
SET #end = CharIndex(',', #StringArray, #end)
INSERT INTO #tbl_string
SELECT
Substring(#StringArray, #start, #end-#start)
SET #start=#end+1
SET #end = #end+1
END
RETURN
END
And then to use the function...
SELECT *
FROM table
WHERE SomeFieldValue In (Select ParsedString From dbo.ParseStringList(#Types))
It's because you need to have a set of values separated by commas. Like
WHERE
T.TYPE_ID IN ('46', '45', '44');
Are you usign SQL Server or Oracle, MySQL?
If you have a string composed of your multiple values such as
T.TYPE_ID IN ('46,45,44');
You might need a function that will explode your string usign a delimiter (split or whatever it is called depending on you DBMS)
The following Select working fine for me:
SELECT M.REG_NO, T.TYPE_ID
FROM MAIN AS M
INNER JOIN CLASSIFICATION AS C
ON M.REG_NO = C.REG_NO
INNER JOIN TYPE AS T
ON T.TYPE_ID = C.TYPE_ID
WHERE (','+#Types+',') LIKE '%,' +T.TYPE_ID+ ',%'
how can i write the store procedure for searching particular string in a column of table, for given set of strings (CSV string).
like : select * from xxx where tags like ('oscar','rahman','slumdog')
how can i write the procedure for that combination of tags.
To create a comma seperated string...
You could then apply this list to Oded example to create the LIKE parts of the WHERE cluase on the fly.
DECLARE #pos int, #curruntLocation char(20), #input varchar(2048)
SELECT #pos=0
SELECT #input = 'oscar,rahman,slumdog'
SELECT #input = #input + ','
CREATE TABLE #tempTable (temp varchar(100) )
WHILE CHARINDEX(',',#input) > 0
BEGIN
SELECT #pos=CHARINDEX(',',#input)
SELECT #curruntLocation = RTRIM(LTRIM(SUBSTRING(#input,1,#pos-1)))
INSERT INTO #tempTable (temp) VALUES (#curruntLocation)
SELECT #input=SUBSTRING(#input,#pos+1,2048)
END
SELECT * FROM #tempTable
DR0P TABLE #tempTable
First off, the use of like for exact matches is sub-optimal. Might as well use =, and if doing so, you can use the IN syntax:
select * from xxx
where tags IN ('oscar', 'rahman', 'slumdog')
I am guessing you are not looking for an exact match, but for any record where the tags field contains all of the tags.
This would be something like this:
select * from xxx
where tags like '%oscar%'
and tags like '%rahman%'
and tags like '%slumdog%'
This would be not be very fast or performant though.
Think about moving this kind of logic into your application, where it is faster and easier to do.
Edit:
Following the comments - there are lots of examples on how to parse delimited strings out there. You can put these in a table and use dynamic sql to generate your query.
But, this will have bad performance and SQL Server will not be able to cache query plans for this kind of thing. As I said above - think about moving this kind of logic to application level.