Using ANY operator together with string functions - sql

I want to build a query like this:
SELECT * FROM T1 WHERE Charindex(ANY(SELECT City FROM Cities),T1ADDRESS)>0
As i understand, the ANY operator cannot stay as SQL functions argument. So, what is the alternative?
Suppose I want to write a UDF that returns 1 or 0 dependent on one input argument Address. How do I do this without for loop operator and without accessing to SELECT City FROM Cities array by index, as it can be done easily in the procedural languages?

Have you tried a JOIN?
SELECT *
FROM T1
INNER JOIN CITIES
ON T1ADDRESS LIKE '%' + City + '%'
Not sure about performance however...

How about,
SELECT
*
FROM
T1
WHERE
EXISTS
(
SELECT City FROM Cities WHERE T1.T1ADDRESS LIKE '%' + City + '%'
)

You might want to do something like this?
SELECT * FROM T1 WHERE Charindex in (SELECT '%'+City+'%' FROM Cities)
which address the ANY problem but not everything you asked for.

Related

Using CONTAINS to find items IN a table

I'm trying to write a SP that will allow users to search on multiple name strings, but supports LIKE functionality. For example, the user's input might be a string 'Scorsese, Kaurismaki, Tarkovsky'. I use a split function to turn that string into a table var, with one column, as follows:
part
------
Scorsese
Kaurismaki
Tarkovsky
Then, normally I would return any values from my table matching any of these values in my table var, with an IN statement:
select * from myTable where lastName IN (select * from #myTableVar)
However, this only returns exact matches, and I need to return partial matches. I'm looking for something like this, but that would actually compile:
select * from myTable where CONTAINS(lastName, select * from #myTableVar)
I've found other questions where it's made clear that you can't combine LIKE and IN, and it's recommended to use CONTAINS. My specific question is, is it possible to combine CONTAINS with a table list of values, as above? If so, what would that syntax look like? If not, any other workarounds to achieve my goal?
I'm using SQL Server 2016, if it makes any difference.
You can use EXISTS
SELECT * FROM myTable M
WHERE
EXISTS( SELECT * FROM #myTableVar V WHERE M.lastName like '%'+ V.part +'%' )
Can your parser built the entire statement? Will that get you what you want?
select *
from myTable
where CONTAINS
(lastName,
'"Scorsese" OR "Kaurismaki" OR "Tarkovsky"'
)
This can be done using CHARINDEX function combined with EXISTS:
select *
from myTable mt
where exists(select 1 from #myTableVar
where charindex(mt.lastName, part) > 0
or charindex(part, mt.lastName) > 0)
You might want to omit one of the conditions in the inner query, but I think this is what you want.

Is it possible to have a where with a select statement which you add wildcards to

I have a situation where I need to use a select statement in a where but then also append and prepend wildcards to the value it returns. E.g something like:
select * from [Customers.customervisibility] where userId like '%,' (Select Id from [Users.Users] where name ='MyName') ',%'
but running this gives:
Incorrect syntax near ',%'.
Now the Select Statement is only ever going to return 1 id, so I don't know if there is a better way to write it maybe using a function.
The overall goal is so that I can select the rows from [customer.customervisibility] where the id is contained in a comma seperated string column [UserId]
e.g. if id = 8
I need to get the rows where *,8,*...
It has to be inline, I cannot use variable, and you will have to excuse the TERRIBLE database design. this is so that it will work with third party software
Try this where clause
If your DBMS support Concat the use this.
userId like concat('%' ,(Select top 1 cast(Id as varchar(50)) from [Users.Users] where name ='MyName') ,'%')
Else
userId like '%' +(Select top 1 cast(Id as varchar(50)) from [Users.Users] where name ='MyName') +'%'
I have used Top 1 to avoid sub-query returns more than one row error if in case your subquery returns more than one row
You seem to have forgotten the concatenation character + for strings. Try below query:
select * from [Customers.customervisibility] where userId like '%,'+(Select Id from [Users.Users] where name ='MyName')+',%'
This will give results whose userId contains your Id where userId is a comma separated string.
SELECT *
FROM [Customers.customervisibility]
WHERE (userId LIKE '% , Select Id from [Users.Users] where status="MyName" %')
Try this:
select * from [Customers.customervisibility] where convert(VARCHAR(100),userId) like '%'+(Select Id from [Users.Users] where name ='MyName')+'%'

SQL: Correctly identify and correct(if possible) names in database

I have a large database of names, and I'm hoping to identify incorrect capitalization.
Right now I'm using the following...
SELECT *
FROM myTable
WHERE LastName LIKE '%Mcd%' COLLATE SQL_Latin1_General_Cp1_CS_AS
Now of course this is inefficent because I have to run/edit this over and over for different cases. My thinking is find a list of name cases that would provide possible problems, and do
LIKE IN ('case1','case2','case3','case4', ...)
if that's possible. Is there another way that I'm not thinking of?
Other cases I'm thinking I'll have to check are abbreviations (%.%), hypens (%-%), and apostrophes (%'%).
You could use
SELECT *
FROM myTable
WHERE LastName LIKE '%Mcd%' or LastName LIKE '%Foo%'
Or
WITH T(Word) AS
(
SELECT 'Mcd' UNION ALL
SELECT 'Foo'
)
SELECT *
FROM myTable
JOIN T ON LastName LIKE '%' + Word + '%'
To avoid needing to scan myTable multiple times.
To avoid processing the string multiple times you could use CLR and Regular Expressions.

SQL Server using wildcard within IN

Since I believe this should be a basic question I know this question has probably been asked, but I am unable to find it. I'm probably about to earn my Peer Pressure badge, but I'll ask anyway:
Is there a way in SQL Server that I am not aware of for using the wildcard character % when using IN.
I realize that I can use OR's like:
select *
from jobdetails
where job_no like '0711%' or job_no like '0712%'
and in some cases I can use a subquery like:
select *
from jobdetails
where job_no in (select job_no from jobs where job_id = 39)
but I'm looking to do something like the following:
select *
from jobdetails
where job_no in ('0711%', '0712%')
In this case it uses the percent sign as a character instead of a wildcard character so no rows are returned. I currently just use a bunch of OR's when I have to do this, but I know there has to be a better way. What method do you use for this?
How about:
WHERE LEFT(job_no, 4) IN ('0711', '0712', ...)
I think I have a solution to what the originator of this inquiry wanted in simple form. It works for me and actually it is the reason I came on here to begin with. I believe just using parentheses around the column like '%text%' in combination with ORs will do it.
select * from tableName
where (sameColumnName like '%findThis%' or sameColumnName like '%andThis%' or
sameColumnName like '%thisToo%' or sameColumnName like '%andOneMore%')
How about something like this?
declare #search table
(
searchString varchar(10)
)
-- add whatever criteria you want...
insert into #search select '0711%' union select '0712%'
select j.*
from jobdetails j
join #search s on j.job_no like s.searchString
You could try something like this:
select *
from jobdetails
where job_no like '071[12]%'
Not exactly what you're asking, but it has the same effect, and is flexible in other ways too :)
SELECT c.* FROM(
SELECT '071235' AS token UNION ALL SELECT '07113'
UNION ALL SELECT '071343'
UNION ALL SELECT '0713SA'
UNION ALL SELECT '071443') AS c
JOIN (
SELECT '0712%' AS pattern UNION ALL SELECT '0711%'
UNION ALL SELECT '071343') AS d
ON c.token LIKE d.pattern
071235
07113
071343
I had a similar goal - and came to this solution:
select *
from jobdetails as JD
where not exists ( select code from table_of_codes as TC
where JD.job_no like TC.code )
I'm assuming that your various codes ('0711%', '0712%', etc), including the %, are stored in a table, which I'm calling *table_of_codes*, with field code.
If the % is not stored in the table of codes, just concatenate the '%'. For example:
select *
from jobdetails as JD
where not exists ( select code from table_of_codes as TC
where JD.job_no like concat(TC.code, '%') )
The concat() function may vary depending on the particular database, as far as I know.
I hope that it helps. I adapted it from:
http://us.generation-nt.com/answer/subquery-wildcards-help-199505721.html
I firstly added one off static table with ALL possibilities of my wildcard results
(this company has a 4 character nvarchar code as their localities and they wildcard their locals)
i.e. they may have 456? which would give them 456[1] to 456[Z] i.e 0-9 & a-z
I had to write a script to pull the current user (declare them) and pull the masks for the declared user.
Create some temporary tables just basic ones to rank the row numbers for this current user
loop through each result (YOUR Or this Or that etc...)
Insert into the test Table.
Here is the script I used:
Drop Table #UserMasks
Drop Table #TESTUserMasks
Create Table #TESTUserMasks (
[User] [Int] NOT NULL,
[Mask] [Nvarchar](10) NOT NULL)
Create Table #UserMasks (
[RN] [Int] NOT NULL,
[Mask] [Nvarchar](10) NOT NULL)
DECLARE #User INT
SET #User = 74054
Insert Into #UserMasks
select ROW_NUMBER() OVER ( PARTITION BY ProntoUserID ORDER BY Id DESC) AS RN,
REPLACE(mask,'?','') Mask
from dbo.Access_Masks
where prontouserid = #User
DECLARE #TopFlag INT
SET #TopFlag = 1
WHILE (#TopFlag <=(select COUNT(*) from #UserMasks))
BEGIN
Insert Into #TestUserMasks
select (#User),Code from dbo.MaskArrayLookupTable
where code like (select Mask + '%' from #UserMasks Where RN = #TopFlag)
SET #TopFlag = #TopFlag + 1
END
GO
select * from #TESTUserMasks
As Jeremy Smith posted it, i'll recap, since I couldn't answer to that particular question of his.
select *
from jobdetails
where job_no like '071[1-2]%'
If you just need 0711% and 0712% you can also place a ranges within the brackets. For the NOT keyword you could also use [^1-2]%
The IN operator is nothing but a fancy OR of '=' comparisons. In fact it is so 'nothing but' that in SQL 2000 there was a stack overflow bug due to expansion of the IN into ORs when the list contained about 10k entries (yes, there are people writing 10k IN entries...). So you can't use any wildcard matching in it.
In Access SQL, I would use this. I'd imagine that SQLserver has the same syntax.
select *
from jobdetails
where job_no like "0711*" or job_no like "0712*"
A bit late to the party, but you could use STRING_SPLIT
SELECT jobdetails.*
FROM jobdetails
CROSS APPLY (select value
from STRING_SPLIT('540%,%144,orange,coconut',',')
WHERE jobdetails.job_no
like value) as leek
It wouldn't take very much more work to turn that into a reusable function
I had this same question and found a very simple solution using the SUBSTRING function in the WHERE clause. This will not affect how the job_no displays in the return, rather it just trims the IN search down based on the criteria entered for the substring function.
The advantage of using SUBSTRING versus LEFT or RIGHT is that you can define the starting character so if you just want to search the middle of a string, you can do so.
SELECT *
FROM jobdetails
WHERE SUBSTRING(job_no, 1, 4) IN ('0711', '0712')
You have the answer right there in your question. You cannot directly pass wildcard when using IN. However, you can use a sub-query.
Try this:
select *
from jobdetails
where job_no in (
select job_no
from jobdetails
where job_no like '0711%' or job_no like '0712%')
)
I know that this looks crazy, as you can just stick to using OR in your WHERE clause. why the subquery? How ever, the subquery approach will be useful when you have to match details from a different source.
Raj
Try this
select *
from jobdetails
where job_no between '0711' and '0713'
the only problem is that job '0713' is going to be returned as well
so can use '07299999999999' or just add and job_no <> '0713'
Dan zamir
I'm just learning this stuff but would this work?
select *
from jobdetails
where job_no regexp "^(071)[1|2]";
This might me the most simple solution use like any
select *
from jobdetails
where job_no like any ('0711%', '0712%')
In Teradata this works fine.

Is there any way to combine IN with LIKE in an SQL statement?

I am trying to find a way, if possible, to use IN and LIKE together. What I want to accomplish is putting a subquery that pulls up a list of data into an IN statement. The problem is the list of data contains wildcards. Is there any way to do this?
Just something I was curious on.
Example of data in the 2 tables
Parent table
ID Office_Code Employee_Name
1 GG234 Tom
2 GG654 Bill
3 PQ123 Chris
Second table
ID Code_Wildcard
1 GG%
2 PQ%
Clarifying note (via third-party)
Since I'm seeing several responses which don't seems to address what Ziltoid asks, I thought I try clarifying what I think he means.
In SQL, "WHERE col IN (1,2,3)" is roughly the equivalent of "WHERE col = 1 OR col = 2 OR col = 3".
He's looking for something which I'll pseudo-code as
WHERE col IN_LIKE ('A%', 'TH%E', '%C')
which would be roughly the equivalent of
WHERE col LIKE 'A%' OR col LIKE 'TH%E' OR col LIKE '%C'
The Regex answers seem to come closest; the rest seem way off the mark.
I'm not sure which database you're using, but with Oracle you could accomplish something equivalent by aliasing your subquery in the FROM clause rather than using it in an IN clause. Using your example:
select p.*
from
(select code_wildcard
from second
where id = 1) s
join parent p
on p.office_code like s.code_wildcard
In MySQL, use REGEXP:
WHERE field1 REGEXP('(value1)|(value2)|(value3)')
Same in Oracle:
WHERE REGEXP_LIKE(field1, '(value1)|(value2)|(value3)')
Do you mean somethign like:
select * FROM table where column IN (
SELECT column from table where column like '%%'
)
Really this should be written like:
SELECT * FROM table where column like '%%'
Using a sub select query is really beneficial when you have to pull records based on a set of logic that you won't want in the main query.
something like:
SELECT * FROM TableA WHERE TableA_IdColumn IN
(
SELECT TableA_IdColumn FROM TableB WHERE TableA_IDColumn like '%%'
)
update to question:
You can't combine an IN statement with a like statement:
You'll have to do three different like statements to search on the various wildcards.
You could use a LIKE statement to obtain a list of IDs and then use that in the IN statement.
But you can't directly combine IN and LIKE.
Perhaps something like this?
SELECT DISTINCT
my_column
FROM
My_Table T
INNER JOIN My_List_Of_Value V ON
T.my_column LIKE '%' + V.search_value + '%'
In this example I've used a table with the values for simplicity, but you could easily change that to a subquery. If you have a large list (like tens of thousands) then performance might be rough.
select *
from parent
where exists( select *
from second
where office_code like trim( code_wildcard ) );
Trim code_wildcard just in case it has trailing blanks.
You could do the Like part in a subquery perhaps?
Select * From TableA Where X in (Select A from TableB where B Like '%123%')
tsql has the contains statement for a full-text-search enabled table.
CONTAINS(Description, '"sea*" OR "bread*"')
If I'm reading the question correctly, we want all Parent rows that have an Office_code that matches any Code_Wildcard in the "Second" table.
In Oracle, at least, this query achieves that:
SELECT *
FROM parent, second
WHERE office_code LIKE code_wildcard;
Am I missing something?