MySQL: JOIN two tables on LIKE - sql

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.

Related

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 || '%'

How can I check if any items in an array are substrings in one of the columns in my table in PostgreSQL?

I'm not sure how to go about this:
I have a column named description in my database. I have a list of keywords. I want to select the rows where the description contains at least one of the strings in my list.
The list is of strings, and the description is of type TEXT.
I just don't want to do a hideous brute force method of doing multiple LIKEs (because my list is currently 50 elements).
I think you can use a SQL query like this (just I write it on the fly):
WITH tags(tag) AS (
SELECT * FROM (VALUES ('tag1'),('tag2'),('tag3'),('tag4')) AS tags(tag))
SELECT DISTINCT description
FROM tbl
WHERE (description LIKE '%' || tag || '%');
That you can insert your list instead of ('tag1'),('tag2'),('tag3'),('tag4'). That you need something like "(" + replace(yorTagString, ",", "),(") + ")".
[SQL Fiddle Demo]

Select field on multiple values

I am currently trying to create a query where i want to select rows if one field contains multiple values. I think ill just give you an example:
Database: field="Ground;Lava;Rocks"
Query should be: select where field contains "Ground" and "Rocks".
My first attempt would have been:
SELECT * FROM TerrainLayer WHERE tags LIKE '%Ground%' AND tags LIKE '%Rocks%';
Would this be an acceptable solution or are the better (more efficient) ways to achieve this? Thank you in advance for your help.
Something like this should also work, and if you have multiple LIKE clauses should be a little more efficient:
SQL
CREATE TABLE #SearchItem (Search varchar(255))
INSERT INTO #SearchItem VALUES
('Ground'),
('Rocks'),
('Whatever')
SELECT *
FROM TerrainLayer as t
JOIN #SearchItem as s
ON t.tags COLLATE DATABASE_DEFAULT LIKE '% ' + s.Search + ' %'
For SQLite
CREATE TABLE SearchItem (Search varchar(255))
INSERT INTO SearchItem VALUES
('Ground'),
('Rocks'),
('Whatever')
SELECT *
FROM TerrainLayer as t
JOIN #SearchItem as s
ON t.tags LIKE '% ' + s.Search + ' %'
From what I tested a JOIN like this will be quicker. Obviously, you wouldn't need to manually populate the #SearchItem table like this.
try this:
SELECT * FROM TerrainLayer WHERE tags LIKE '%Ground%Rocks%';

"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)
);

Using ANY operator together with string functions

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.