SQL Where Column Value in Query String - sql

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.

Related

substring match on both tables of a join

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.

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

SQLite query to get distinct columns

I am trying to write a query where I need to check whether a value is not present in an array of strings returned by another nested query how can I do that,
For example I have to check whether,
1234 is present in [abc_1234,fgh_12345,ghi_5343]
Hence 1234 is present in string abc_1234 so I will not select 1234.
I hope I understand your request correctly. You have a query returning strings, e.g. 'abc_1234' and 'fgh_12345'. You have a table with values, e.g. '1234'. You want to select rows from the table where the value is not part of any of the strings of the existing query.
This is where the anti-join pattern comes into play. You outer-join the undesired rows, so all rows that found no partner are the desired ones:
select *
from mytable m
left join (<your query here>) q on instr(q.string, m.value) > 0
where q.string is null;
(Instead of INSTR you can also use LIKE: on q.string like '%' || m.value || '%'. It should not matter which of the string operations you choose.)

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]

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