LIKE comparison with IN operator - sql-server

I want to perform a LIKE style comparison with an IN operator e.g.:
select *
from tbl1
where tbl1.value_to_check in (select allowed_str from allowedvalues)
Where allowed values could contain the following allowed_str:
ab% (allow any string starting ab)
%ab (allow any string ending ab)
The above query obviously does not work in this way however is there a way of achieving this using SQL Server 2008?

No, IN does not support this. Try:
SELECT t1.*
FROM dbo.tbl1 AS t1
INNER JOIN dbo.allowedvalues AS a
ON t1.value_to_check LIKE '%' + a.allowed_str + '%';
As Damien points out, if you are storing ab% and %ab separately, rather than just ab on its own, then you just need:
SELECT t1.*
FROM dbo.tbl1 AS t1
INNER JOIN dbo.allowedvalues AS a
ON t1.value_to_check LIKE a.allowed_str;

I believe the exists clause matches better with the original query.
select *
from tbl1
where exists (select 1
from allowedvalues
where tbl1.value_to_check like '%' + a.allowed_str + '%';)
Note: this will cause a table scan on tbl1 (and might be very slow)

Related

SQL Query in which the WHERE clause uses LIKE on all data from a column in another table

Azure SQL Server 2017:
We have a table called dbo.keywords with one column, called keywords. This column consists of ~10,000 varchar(50) entries.
We have another table called dbo.articles. Both tables are in the same database.
The query we are trying to create would be such:
SELECT * FROM dbo.articles
WHERE TextValue LIKE
(**any of the 10,000 values of the keywords column in the dbo.keywords table**).
The part in the parentheses above is the part that I am unclear on accomplishing. If not for the LIKE part, I suppose I could use a SELECT subquery, but the LIKE piece is what's throwing me.
I suspect that this will be the more "perfomant" option (I use quotes, as using LIKE with a leading wildcard will make the query non-SARGable):
SELECT *
FROM dbo.articles a
WHERE EXISTS (SELECT 1
FROM dbo.keywords k
WHERE a.TextValue LIKE '%' + k.keyword + '%');
This will avoid duplicate rows, and a costly DISTINCT; as I suspect that TextValue could have some lengthy values.
You can achieve it by using JOIN with LIKE.
Could you please try the query below:
SELECT *
FROM dbo.articles [AR]
INNER JOIN dbo.keywords [KW] ON [AR].TextValue LIKE '%' + [KW].keywords + '%';
You'll want to join the tables, and use the LIKE clause in the join condition:
SELECT DISTINCT a.* FROM dbo.articles a
JOIN dbo.keywords k ON a.TextValue LIKE '%' + k.keywords + '%';

SQL Server loop programming

For Sql Server 2014, what syntax do I need, if this is even possible?
(in pseudo-code)
DECLARE #searchstring nvarchar(20)
LOOP #searchstringstring = (SELECT keyword FROM table1)
SELECT column FROM table2 where column LIKE '%#searchstring%'
END LOOP
I want it to return all columns in a single table.
Unless I'm missing something, you want to select all the values in table2.Column that contains the text in table2.Keyword. This can be done easily with a simple inner join:
SELECT t2.column
FROM table2 t2
INNER JOIN table1 t1 ON(t2.column LIKE '%'+ t1.keyword +'%'
Sql works best with set based operations. looping is rarely the desired approach.

Finding the difference between two tables based on a common key (Microsoft SQL Server)

I have two tables that share a common key and a few different columns. The common key is CampaignID. One of the tables has slightly more CampaignID's than the other one and I would like to find out the difference between those two tables. Currently, I am using LEFT OUTER JOIN and CTE to merge these two tables first, then by inspecting NULL columns in the CTE result set derived in the earlier step to count the difference in CampaignID column. For instance,
WITH CTE_Results
AS (SELECT t1.CampaignID AS cd_CampaignID,
t2.CampaignID AS cod_CampaignID,
t1.NAME,
t2.Vendor
FROM CampaignDetails AS t1
LEFT OUTER JOIN CampaignOnlineDetails AS t2
ON t1.CampaignID = t2.CampaignID)
-- Now that I have CTE result, I'll use another SELECT to find the difference
SELECT cd_CampaignID, cod_CampaignID
FROM CTE_Results
WHERE cod_CampaignID is NULL
But this seems inefficient to me. Is there a more efficient/faster way to compare the difference in a specific column between two tables in Microsoft SQL Server? Thank you for your answers!
NOTE: I'm new to Microsoft SQL Server and SQL in general.
If one table has more than the other then how bout:
SELECT C1.* FROM CAMPAIGN_WITH_MORE_DATA AS C1
WHERE NOT EXISTS(SELECT * FROM CAMPAIGN_WITH_LESS_DATA AS C2
WHERE C2.CAMPAIGN_ID = C1.CAMPAIGN_ID)
If either may have one campaign or not then UNION this:
SELECT C1.Name AS [Col1],
C1.CAMPAIGN_ID,
'More Campaigns' AS [Source]
FROM CAMPAIGN_WITH_MORE_DATA AS C1
WHERE NOT EXISTS(SELECT * FROM CAMPAIGN_WITH_LESS_DATA AS C2
WHERE C2.CAMPAIGN_ID = C1.CAMPAIGN_ID)
UNION ALL
SELECT C2.Vendor AS [Col1],
C2.CAMPAIGN_ID,
'Less Campaigns' AS [Source]
FROM CAMPAIGN_WITH_LESS_DATA AS C2
WHERE NOT EXISTS(SELECT * FROM CAMPAIGN_WITH_MORE_DATA AS C1
WHERE C1.CAMPAIGN_ID = C2.CAMPAIGN_ID)
Not exists is likely more efficient than a left join. This'll work too:
SELECT CampaignID FROM CampaignDetails
EXCEPT
SELECT CampaignID FROM CampaignOnlineDetails
Just reverse order to check the other way round.

SQL Server : make a select and test every occurrence/row inside another select

I have a SQL Server stored procedure that receives a comma separated string as parameter.
I also have a table-valued function that takes this parameter, splits it (between the commas) and returns as a 'table'.
This procedures is a 'search procedure' that uses LIKE operator to find matching terms.
How can I loop through this parameter that has been transformed into a table and compare it with LIKE?
The sequence that I'd need is something like this:
SQL Server procedure has been called and a separated comma string has been passed as parameter.
A table-valued function gets called to strip this string and transform it in a result table. (It´s not a real table, its just the results). Until here I have already done, the next part is the one I need help:
Loop through this recently created 'table' and search in a specific column of another table.
eg.
SELECT *
FROM tbl_names
WHERE col_names LIKE '%' + (the search term here) + '%'
You can join your table on result of your function:
select * from SomeTable st
join dbo.SomeFunction(#str) sf on st.SomeColumn like '%' + sf.Term +'%'
To order by occurences do something like this:
select * from SomeTable st
join(
select st.ID, count(*) as Occurence from SomeTable st
join dbo.SomeFunction(#str) sf on st.SomeColumn like '%' + sf.Term +'%'
group by st.ID) ot on st.ID = ot.ID
order by ot.Occurence desc
I'd probably use a cross or outer apply with patindex if you want to know how many items matched
select S.*, m.matches
from sometable s
cross apply (select count(1) as matches from finction where patindex ('%' + function.Column + '%', s.coltosearch) > 1) as matched
Use cross apply if you only want to return rows that have matches and outer if you want all rows with a count of terms.
Note: Code example is untested

DISTINCTROW equivalent in SQL Server

Could you please tell me if there is any equivalent of Access' DISTINCTROW for SQL Server?
From reading the documentation on distinctrow, it looks like you want an exists clause or (for generally better performance) a join:
SELECT * FROM A
WHERE EXISTS(SELECT * FROM B WHERE B.a_id = A.a_id)
SELECT DISTINCT A.* FROM A
INNER JOIN B ON A.a_id = B.a_id
-- corrected, should be inner join here
SQL server doesn't support DISTINCTROW instead you should use the keyword DISTINCT
But the answer that Chris Shain has given gives you what you want.
You can just use the keyword DISTINCT instead.

Resources