SQL issue with using concatenation inside "like" - sql

I'm trying to use subquery inside "like", sth like this:
select *
from message c
where c.content like (select concat('%', value, '%')
from objects o
where o.orderid = '70008090102484');
and it's returning no results. When I copy paste the output of the select instead of it, it returns one row, so I've tried this:
select *
from message c
where c.content like concat('%', '123', '%'); - no results
select *
from message c
where c.content like '%123%';* - 1 result
I've tried with '%' || '123' || '%' and the same result.
Does anybody have any idea why this is happening?
EDIT: "content" field is of type "bytea" - for varchar it works fine, unfortunately, I'm unable to change this field type

Your first query can be phrased using exists in a structurally-similar way:
SELECT *
FROM message c
WHERE EXISTS (
SELECT 1
FROM objects o
WHERE c.content LIKE CONCAT('%', o.value, '%') AND
o.orderid = '70008090102484'
);

Related

How do I use a like in a join with SQL92?

I'm trying to use a like in a join statement. My reason I have one field that is a varchar and another that is also a varchar however, the second field is a comma separated list.
SELECT c.Class, c.SubClass, c.Value, c.Pairs, c.Description, prodt.ProductType, p.Type
FROM pub.table1 c
INNER JOIN pub.Table2 p ON c.SubClass like CONCAT(CONCAT('%',p.Type),'%')
INNER JOIN pub.Table3 prodt ON p.ProdType = prodt.ProductType
WHERE c.Class = 'whatever'
In this case p.Type is the comma separated list and the SubClass is the normal varchar.
I have tried using a few different things already. I would have thought the below worked, but it did not.
INNER JOIN pub.Table2 p ON c.SubClass like '%' + p.Type +'%'
Is there a way to do this or do i have do something different like another select with SQL92? Thank you in advance!
From your explanation, you need to swap the LIKE since p.Type contains the list of values.
p.Type like '%' + c.SubClass + '%'
Your code:
SELECT c.Class, c.SubClass, c.Value, c.Pairs, c.Description, prodt.ProductType, p.Type
FROM pub.table1 c
INNER JOIN pub.Table2 p ON p.Type like '%' || c.SubClass || '% '
INNER JOIN pub.Table3 prodt ON p.ProdType = prodt.ProductType
WHERE c.Class = 'whatever'
Here's a sample test to show this:
select 'matched'
where 'abc' like '%abc,def,ghi,jkl%'
select 'matched'
where 'abc,def,ghi,jkl' like '%abc%'
I am guessing that you want something like this:
ON ',' || p.type || ',' like '%,' || c.subsclass || ',%'
|| has been the string concatenation operator in ISO/ANSI SQL for a long time. To be honest, I don't remember if the adoption of this operator dates back 26 years.

SQL query to find matches

I have written a query to provide matches with the same DB and it's giving me expected results except that I don't get few part of it. Below is the query :
select f.name, f.id, f.industry, d.name, d.id, d.industry
from product_table f, product_table d
where (f.name like '%' || d.name || '%') and
(f.industrylike '%' || d.industry|| '%') and
I know by providing this it's actually looking for matches between the 2 columns :
(..... like '%' || ..... || '%')
But what does each part of it do exactly and what does it mean?
This query is executing a self-join (here, a cross self-join) in which we query two instances of the same table for some purpose. In this case it looks like some form of data quality exercise, where we suspect we might have almost duplicate records. That is, we think we have records for the same combination of (product name and industry). The use of wild cards will identify records where the value of one column is wholly embedded in another column: for instance '%STACK%' matches 'META STACKOVERFLOW'.
The posted version has a potential flaw, in that if there are two records with an exact match you will get two hits (one for F:D, one for D:F). You can finagle that by adding a filter on id
select f.name, f.id, f.industry,
d.name, d.id, d.industry
from product_table f, product_table d
where (f.name like '%' || d.name || '%')
and (f.industrylike '%' || d.industry|| '%')
and ( ( f.name = d.name
and f.industry = d.industry
and f.id < d.id )
or f.name != d.name
or f.industry != d.industry
)
The double vertical bar (more commonly known as a pipe) is the concatenation operator. It is used for joining strings together. (Many programming languages use + but Oracle reserves that strictly for arithmetic on numbers.)
not so much clear on why we put it before and after only the second column : f.name like '%' || d.name || '%'
In this case, the query is concatenating a wild card. Given this value for f.name = 'XYZ' , we would get matches for '%' || d.name || '%' on:
'1XYZ1'
'11XYZ11'
'11XYZ'
'XYZ1'
'XYZ' <---- matching same record
We don't need to wrap f.name in wildcard operators because the query is a self-join so all the values of name will appear on the left hand side of the filter. When f.name = '1XYZ1' it match for '%' || d.name || '%' on:
'1XYZ1' <---- matching same record
'XYZ1'
'XYZ'
So you're going to get multiple hits already. Embedding both sides of the filter in wildcards will only generate more noisy duplicates.

Oracle sql like multiple conditions with select from other table

I have 375 dialcodes in table "temp":
917277
917278
918083
...
9172738
I can do the following:
select * from cdr where
dnis like 917277% or
dnis like 917278% or
dnis like 918083% or
...
dnis like 9172738%
Is it possible to make a query including "select in" and "like %" conditions?
select * from cdr where dnis in (select dialcode% from temp)
One method is to use exists:
select c.*
from cdr c
where exists (select 1 from temp t where c.dnis like dialcode || '%' );
Note that this does not require distinct, even when there might be multiple matches.
You can use JOIN and LIKE to achieve similiar result:
SELECT c.* -- DISTINCT may be needed if dialcodes overlap each other
FROM cdr c
JOIN temp t
ON c.dnis LIKE t.dialcode || '%'

Search string in SQL with action on table

I found on internet some stored procedure to search string in database, regularly it's used by table name.
My procedure contains a SELECT statement like this:
select distinct s.name
from sysobjects s
inner join syscomments c on c.id = s.id
and charindex(#keyword,c.text) > 0
where s.type IN ('V', 'P')
order by 1
My action want more than this, I want to search table name with action on that like insert, update or select. It means only find table name(keyword) has action insert or update or select and show me where it's used (procedure name, view...)
Is it possible to do?
First, dont use sysobjects and syscomments as they have been deprecated for quite some time now.
If you just care that the word appears in the object text, you can use a wildcard search like this
select top 100 *
from sys.sql_modules sm
inner join (select searchString = 'insert' union all
select searchString = 'update' union all
select searchString = 'delete') x
on sm.definition like '%' + x.searchString + '%'

select record in one table that are not in another with a pattern match

I would like to find all records in the column of one table that are not in a column of another. I can do so with this query:
SELECT
kywd
FROM
from_client
WHERE
kywd NOT IN
(SELECT
kywd
FROM
from_me);
However, I would like to extend this to allow for some pattern matching. At the very least I'd like to see if the from_client kywd appears anywhere in the from_me kywd. So, like, '%kywd%'. I tried ...WHERE '%' || kywd || '%' NOT IN... as a wild guess, and a result set was actually returned, but I suspect this syntax is just gibberish.
How can I make this select statement allow for these wildcards?
not exists is likely to be faster than join
select kywd
from from_client
where not exists (
select 1
from from_me
where position(from_client.kywd, kywd) > 0
)
SELECT from_client.kywd
FROM from_client
LEFT JOIN from_me
ON from_client.kywd LIKE '%' || from_me.kywd || '%'
WHERE from_me.kywd IS NULL
You could try to use the EXCEPT statement. In you scenarion it would be something like
SELECT kywd
FROM from_client
--WHERE <Conditions here>
except
SELECT kywd
FROM from_me
--WHERE <Conditions here>
and returns what exists in from_client that does not exists in from_me.
Try something along these lines.
SELECT
kywd
FROM
from_client
LEFT OUTER JOIN from_me ON
from_client.kywd like from_me.kywd -- replace with whatever appropriate
WHERE
from_me.some_id IS NULL
By "replace with whatever appropriate", I mean:
from_client.kywd LIKE '%' || from_me.kywd || '%'
or
from_me.kywd LIKE '%' || from_client.kywd || '%'
or any other condition which is appropriate there.