substring match on both tables of a join - sql

How can I perform joins on a substring match to another substring. I seem to only be able to ilike search on one or the other, not substring search both.
Given tables:
DIALOG
string
-------------------
Hi, my name is dan
STRUCTURES
structure
----------
his name is / my name is
hello, my / you are
how are you?
EXPECTED OUTPUT:
string | structure
-------------------------------
Hi, my name is dan | his name is / my name is
Attempts:
Two ilike fuzzy matches:
select string, structure from dialog left join structures on ('%' || string || '%' ilike '%' || structure || '%');
Two fuzzy ilike matches with OR:
select string, structure from dialog left join structures on (string ilike '%' || structure || '%') or (structure ilike '%' || string || '%');
Both output:
string | structure
-------------------------------
Hi, my name is dan |

If the structures actually matches, you could use regular expressions:
select string, structure
from dialog d left join
structures s
on string ~ replace(string, ' / ', '|');
Of course, this doesn't work on the sample data, because the strings don't actually match.
This also suggests that your structure should actually be a regular expression.

Perform a cartesian product first, limited with a WHERE clause, to see what kind of results you can expect.
select string, structure from dialog CROSS join structures WHERE string ilike '%' || structure || '%' AND structure ilike '%' || string || '%'
I think your left join attempt does not match anything because there's wildcards on the left side of the ILIKE statement. These are, afaik, taken literally. Also, use 'AND' for the join: you want the couples where both of the predicates are true. The cross join fits OK here, as you define your where clause pretty tightly.
The left join would only be used where you want to absolutely get your 'dialog', with optionally 'structure' connected to it. In this case, do the 'full join', so you can see exactly what kind of matches are made. Later on, you can decide to further filter everything out and put the where clause predicates in suitable join clause.

Related

SQL Where Column Value in Query String

I'm trying to build a query that will match with records that have values that are contained in the query string.
For example if I have a Product table with brand and name columns I would want the following query string Ford engine for car to match with a record where the brand is set to Ford and the name is set to V8 Engine.
I originally tried using the IN operator but that's not quite what I need. The query needs to be the reverse of a LIKE such that if the column value is contained in the query string then the record will match for that query.
Hmmmm . . . I think this does what you want:
select p.*
from product p
where $query_string like '%' || brand || '%' and
$query_string like '%' || name || '%' ;
Performance is a different matter. If that is a concern, perhaps a full text index would help.

SQL: finding similar rows to other same table in special column

I am using SQLITE for running this query:
SELECT * FROM phrases1, phrases2 WHERE phrases1.word LIKE ('%' +phrases2.word+ '%')
but not works.
two tables phrases1, phrases2 are same and have column name word and I want to filter the first table by rows that word column is similar to the word column of second table . while this works:
SELECT * FROM phrases1, phrases2 WHERE phrases1.word LIKE phrases2.word
but I want to use wildcards.
The SQLite operator for string concatenation is || not +:
SELECT * FROM phrases1, phrases2
WHERE phrases1.word LIKE '%' || phrases2.word || '%'
Also I don't know what the effect of having parentheses around your LIKE expression would be, but you don't need them there. But you should really write your query using explicit joins, better yet use aliases too:
SELECT *
FROM phrases1 p1
INNER JOIN phrases2 p2
ON p1.word LIKE '%' || p2.word || '%'

"NOT IN" subquery with a leading wildcard

I have two tables:
Table tablefoo contains a column fulldata.
Table tablebar contains a column partialdata.
I want find a list of tablefoo.fulldata that do NOT have partial matches in tablebar.partialdata.
The following provides a list of tablefoo.fulldata with partial matches in tablebar, but I want the negative of this.
select fulldata from tablefoo
where fulldata like any (select '%' || partialdata from tablebar);
This lists every record in partialdata:
select fulldata from tablefoow
where partialdata not in (select '%' || partialdata from tablebar);
Any idea how to get only the results tablefoo.fulldata that do not contain matches to a leading wildcarded tablebar.partialdata?
I found this link: PostgreSQL 'NOT IN' and subquery which seems like it's headed down the right path, but I'm not getting it to work with the wildcard.
Sure, I could write a script to pull this out of psql and do the comparisons, but it would be much nicer to handle this all as part of the query.
SELECT fulldata
FROM tablefoo f
WHERE NOT EXISTS (
SELECT 1
FROM tablebar b
WHERE f.fulldata LIKE ('%' || b.partialdata)
);

Oracle SQL: how to search honorofics in a string

I have name fields in my data set. Using Oracle PL SQL, how can I search for the records that contain honorifics?
I have a list of honorifics that I want to search for in a separate table.
Any help would be really appreciated.
Thanks.
I'd use REGEXP_LIKE and do a cross join against the honorifics table.
This query will list all names that have an honorific, plus the honorific. If a name has more than one honorific it will be listed for each match:
SELECT
myTable.Name,
honorifics.Title
FROM myTable
CROSS JOIN honorifics
WHERE REGEXP_LIKE(myTable.Name, ''(\W|^)' || honorifics.Title || '(\W|$)')
The regex checks to see if the honorific title is at the beginning of the string or preceded by a "non-word" character, and if it's at the end of the string or followed by a non-word character.
Note that this search is case sensitive. To make it non-case sensitive, add a third argument of 'i' to the REGEXP_LIKE:
WHERE REGEXP_LIKE(myTable.Name, ''(\W|^)' || honorifics.Title || '(\W|$)', 'i')
^^^^^
SELECT names.lastName
FROM names
INNER JOIN honorophics ON names.lastName LIKE honorophics.listOfHonorophics + '%'
this will join the 2 tables, resulting in the rows, where lastName contains a pattern from the table with honorophics

MySQL: JOIN two tables on LIKE

I have a table with a column containing text, and I want to select all of the tables where the text from one of the rows in a second table appears in that row. Here is a pseudo-query:
SELECT title FROM recipes AS r
JOIN ingredients AS i
ON r.ingredients LIKE '%' + i.name + '%';
The above query does not work, however. How do I do this correctly?
SELECT title
FROM recipes r JOIN ingredients i ON r.ingredients LIKE concat('%', i.name, '%')
MySQL is weird, and makes you use the concat operator to concatenate strings together. Most others use ||
You can't concatenate strings with the + operator (it's for arithmetic only). Use concat('%',i.name,'%') instead.