How to restrict entire FTS5 Query to a single column? - sql

Currently, I'm trying to execute an FTS5 query via libsqlite, and need to restrict the query to a specific column. In FTS4, this was possible by doing:
SELECT foo, bar FROM tableName WHERE columnName MATCH ?
and then binding the search string to the statement. However, with FTS5, the LHS of the MATCH operator must be the FTS table name itself, and the column name must be a part of the query:
SELECT foo, bar FROM tableName WHERE tableName MATCH 'columnName:' || ?.
This works when the binded string is a single phrase. However, consider the search text this is great. The query then becomes:
SELECT foo, bar FROM tableName WHERE tableName MATCH 'columnName:pizza is great';
Only pizza is restricted to to the columnName, but the rest of the phrase is matched against all columns.
How can I work around this?

The documentation says:
A single phrase … may be restricted to matching text within a specified column of the FTS table by prefixing it with the column name followed by a colon character.
So the column name applies only to a single phrase.
If you have three phrases, you need to specify the column name three times:
tableName MATCH 'columnName:pizza columnName:is columnName:great'

Related

How can you filter Snowflake EXPLAIN AS TABULAR syntax when its embedded in the TABLE function? Can you filter it with anything?

I have a table named Posts I would like to count and profile in Snowflake using the current Snowsight UI.
When I return the results via EXPLAIN using TABLULAR I am able to return the set with the combination of TABLE, RESULT_SCAN, and LAST_QUERY_ID functions, but any predicate or filter or column reference seems to fail.
Is there a valid way to do this in Snowflake with the TABLE function or is there another way to query the output of the EXPLAIN using TABLULAR?
-- Works
EXPLAIN using TABULAR SELECT COUNT(*) from Posts;
-- Works
SELECT t.* FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) as t;
-- Does not work
SELECT t.* FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) as t where operation = 'GlobalStats';
-- invalid identifier 'OPERATION', the column does not seem recognized.
Tried the third example and expected the predicate to apply to the function output. I don't understand why the filter works on some TABLE() results and not others.
You need to double quote the column name
where "operation"=
From the Documentation
Note that because the output column names from the DESC USER command
were generated in lowercase, the commands use delimited identifier
notation (double quotes) around the column names in the query to
ensure that the column names in the query match the column names in
the output that was scanned

SQL String Pattern Matching

I am trying to run a simple select query on a table to exclude all the records containing a single word on Snowflake.
For E.g. there is a column - " NAME" having datatype - STRING - containing a single word and combination of words.
I want to build a query to exclude all iterations of a sub-string present in that column ( uppercase,lowercase and camel-case via a single query)
I am trying to run a simple select query on a table to exclude all the records containing a single word
You could use ILIKE to perform case-insensitive comparison:
SELECT *
FROM tab
WHERE NAME NOT ILIKE '%phrase%';
db<>fiddle demo

MariaDB MATCH AGAINST with single quote search term?

I'm trying to find a working query for using MATCH AGAINST while having a search term containing a single quote.
Example data in the database table:
I'm a freak
Example search term:
I'm
Search queries I tried:
SELECT * FROM table WHERE MATCH (name) AGAINST ('"I\'m"' IN NATURAL LANGUAGE MODE);
SELECT * FROM table WHERE MATCH (name) AGAINST ('"I\'m"' IN BOOLEAN MODE);
SELECT * FROM table WHERE MATCH (name) AGAINST ('I\'m*' IN BOOLEAN MODE);
SELECT * FROM table WHERE MATCH (name) AGAINST ('(I\'m)*' IN BOOLEAN MODE);
...and many more. Nothing is working.
I'm using MariaDB 10.1.33.
Any ideas?
I'm pretty sure contractions are not treated as words.
Instead the apostrophe is treated as a word separator giving you "I" and "m".
But you probably don't have innodb_ft_min_token_size=1, so those two "words" are ignored.
There are limitations of FT; you have encountered one of them.

sqlite3 with FTS4 table: Query returns wrong row

I have a weird issue with my FTS4 index in SQLite3, namely that a MATCH query for one term returns not the exact match but another, similar one, and vice versa.
Here is an example to illustrate it better:
SELECT name FROM test_idx WHERE name MATCH 'lehmbruck-museum';
-- "Lehmbruck-Archiv"
SELECT name FROM test_idx WHERE name MATCH 'lehmbruck-archiv';
-- "Lehmbruck-Museum"
It seems to have something to do with the dash, here is a similar case that exhibits the same behavior:
SELECT name FROM test_idx WHERE name MATCH 'some-thing';
-- "some-thang"
SELECT name FROM test_idx WHERE name MATCH 'some-thang';
-- "some-thing"
Here is how this test database is built, in case somebody wants to have a go at reproducing it:
CREATE VIRTUAL TABLE test_idx USING fts4(name);
INSERT INTO test_idx (name) VALUES
('some-thing'), ('some-thang'),
('Lehmbruck-Museum'), ('Lehmbruck-Archiv');
SELECT name FROM test_idx WHERE name MATCH 'lehmbruck-museum';
What you pass to MATCH here is a full text query expression. The - character is a unary operator in that expression language that is a stand in for the NOT set operation, and is certainly giving you your unexpected results. Notably - the exact opposite of what you expect! Of course, it is finding exactly what the query is instructed to find - the string lehmbruck and NOT museum at the end!
You'll need to escape it to get the results you want - or perhaps employ the LIKE operator if you are looking at a single column in a table.
Some more information on this expression language can be found in section 3 of the FTS3 and FTS4 documentation on the SQLite doc site here.

Finding the "&" character in SQL SERVER using a like statement and Wildcards

I need to find the '&' in a string.
SELECT * FROM TABLE WHERE FIELD LIKE ..&...
Things we have tried :
SELECT * FROM TABLE WHERE FIELD LIKE '&&&'
SELECT * FROM TABLE WHERE FIELD LIKE '&\&&'
SELECT * FROM TABLE WHERE FIELD LIKE '&|&&' escape '|'
SELECT * FROM TABLE WHERE FIELD LIKE '&[&]&'
None of these give any results in SQLServer.
Well some give all rows, some give none.
Similar questions that didn't work or were not specific enough.
Find the % character in a LIKE query
How to detect if a string contains special characters?
some old reference Server 2000
http://web.archive.org/web/20150519072547/http://sqlserver2000.databases.aspfaq.com:80/how-do-i-search-for-special-characters-e-g-in-sql-server.html
& isn't a wildcard in SQL, therefore no escaping is needed.
Use % around the value your looking for.
SELECT * FROM TABLE WHERE FIELD LIKE '%&%'
Your statement contains no wildcards, thus is equivalent to WHERE FIELD = '&'.
& isn't a special character in SQL so it doesn't need to be escaped. Just write
WHERE FIELD LIKE '%&%'
to search for entries that contain & somewhere in the field
Be aware though, that this will result in a full table scan as the server can't use any indexes. Had you typed WHERE FIELD LIKE '&%' the server could do a range seek to find all entries starting with &.
If you have a lot of data and can't add any more constraints, you should consider using SQL Server's full-text search to create and use and FTS index, with predicates like CONTAINS or FREETEXT