How to perform SQLite LIKE queries with wildcards not read as wildcards - sqlite

I'm running into a problem in SQLite when querying on text fields that happen to have the _ or % wildcard characters.
I have a table with a 'Name' field I want to query on. Two of my records have the value 'test' and 'te_t' in the 'Name' field I want to query on. If I run a query like below
"SELECT ALL * from Table WHERE Name LIKE 'te_t'"
This will return both the 'te_t' and 'test' records, because of '_' being read as a wildcard. How do I make it so that I only get the 'te_t' record from the above query?
I've done some research on this and read that I should be able to throw a backslash '\' character in front of the wildcard to get it to be read as a normal _ character instead of a wildcard. But when I try the query
"SELECT ALL * from Table WHERE Name LIKE 'te\_t'"
my query returns zero matches.
What am I doing wrong? Is this just not possible in SQLite?

In SQL, you can escape special characters in the LIKE pattern if you declare some escape character with ESCAPE:
SELECT * FROM MyTable WHERE Name LIKE 'te\_t' ESCAPE '\'
(see the documentation)

Related

Lossless SQLite FTS5 search of a substring

Using a FTS5 virtual table returns nothing for postfix searches.
It only can search for the entire word tokens, or for the prefixes of the word tokens if I append * to the search.
For example, it does not find qwerty.png row, if I search for werty.
CREATE TABLE IF NOT EXISTS files (name TEXT, id INTEGER);
INSERT INTO files (name, id) VALUES ('qwerty.png', 1), ('asdfgh.png', 2);
CREATE VIRTUAL TABLE IF NOT EXISTS names USING FTS5(name);
INSERT INTO names (name) SELECT name FROM files;
SELECT *
FROM names
WHERE name MATCH 'werty';
It only works for prefix searches (qwerty, qwer*, qwe*, ...).
I can't use * at the start of the search (*werty), since it produces an error.
Is possibly to make the indexed text search working as if I would use
SELECT *
FROM names
WHERE name like '%wert%';
?
I just want to have the fast search for a substring without the full table scan.
Perhaps try the experimental trigram tokenizer
When using the trigram tokenizer, a query or phrase token may match any sequence of characters within a row, not just a complete token.

SQLITE with special character in the json path

I have a column in sqlite which stores a column with json files and the the key of the json can contain any unicode characters. I have a query to calculate the cardinality of the specific key.
SELECT COUNT(DISTINCT JSON_UNQUOTE(JSON_EXTRACT(dimensions, '$.*abc')))from `definition`
the name is *abc which contains a special character * and used in the json path to the value of the json. the query returns nothing.
In order to read special characters like *, the json path is double-quoted and the above query becomes
SELECT COUNT(DISTINCT JSON_UNQUOTE(JSON_EXTRACT(dimensions, '$."*abc"')))from `definition`
Now I am able to read json path with * but unable to read json path containing a double quote, for example
SELECT COUNT(DISTINCT JSON_UNQUOTE(JSON_EXTRACT(dimensions, '$."a"bc"')))from `definition`
I tried to escape the double quotes in the json path with backslash or one additional double quote but it's not working. Any suggestion would be appreciated.
You usually don't need quotes around the object key name. The double quote in the name of that second one one will need to be escaped, though:
sqlite> CREATE TABLE test(data TEXT);
sqlite> INSERT INTO test VALUES ('{"*abc":1,"foo\"bar":2}');
sqlite> SELECT json_extract(data, '$.*abc') FROM test;
json_extract(data, '$.*abc')
----------------------------
1
sqlite> SELECT json_extract(data, '$.foo\"bar') FROM test;
json_extract(data, '$.foo\"bar')
--------------------------------
2
It's not in the documentation, but after looking at the source code, the path string parsing behavior for object keys is:
When encountering a ., if the next character is a double quote, read up to the next double quote and use the enclosed text as the name. Otherwise, read up to the next . or [ (Or end of string) and use that as the name. There's no parsing of any JSON string escape sequences or anything else fancy in it.
So the only time you really need the quotes is if the key has a . or [ in it. '$."$.abc"' for example. It's harmless to use them unless the name has a double quote, though.

SQLlite comma escape in match query

I have a match query for example:
select * from items where itemdesc MATCH (',')
The data that it returns its complete non sense - something that contains semicolons, dots etc.
The like query returns a correct dataset however.
select * from items where itemdesc like ('%,%')
How do correctly return the data in the MATCH query when I have the comma - the same issue persists with apostrophes, not sure if there are more characters that the match query does not like.
SQlite fts4 virtual tables don't handle punctuations and they just get replaced with the space instead...
https://www.sqlite.org/fts3.html#tokenizer
so what i did was just declare the tokenchars:
"tokenize=unicode61" + " \"" +"tokenchars=.,/?!:;\\"
Your actual search string you have to wrap with quotes as well - MATCH '",*"'
it doesn't handle quotes though....

sqlite3 fts3 multiple columns search including special characters

i am using sqlite3 fts3. (sqlite3 version is 3.7.17)
I tried to search keywords including special characters (ex. #, ?) in multiple columns.
This is my examples.
SELECT * FROM table_name WHERE table_name MATCH
'EMAIL:aaa#test.com OR SUBJECT:is it a question?'
This query have to return a result having email address is 'aaa#test.com' or subject is 'is it a question?'
But this query is not return correct results.
I think that sqlite3 fts3 can't recognize special characters...
How can i solve this problem? :(
To do a phrase query, you must use quotes.
Special characters are filtered out by the default tokenizer; aaa#test.com must be handled as a phrase with three words.

Strange sqlite3 behavior

I'm working on a small SQLite database using the Unix command line sqlite3 command tool. My schema is:
sqlite> .schema
CREATE TABLE status (id text, date integer, status text, mode text);
Now I want to set the column 'mode' to the string "Status" for all entries. However, if I type this:
sqlite> UPDATE status SET mode="Status";
Instead of setting column 'mode' to the string "Status", it sets every entry to the value that is currently in the column 'status'. Instead, if I type the following it does the expected behavior:
sqlite> UPDATE status SET mode='Status';
Is this normal behavior?
This is also a FAQ :-
My WHERE clause expression column1="column1" does not work. It causes every row of the table to be returned, not just the rows where column1 has the value "column1".
Use single-quotes, not double-quotes, around string literals in SQL. This is what the SQL standard requires. Your WHERE clause expression should read: column1='column2'
SQL uses double-quotes around identifiers (column or table names) that contains special characters or which are keywords. So double-quotes are a way of escaping identifier names. Hence, when you say column1="column1" that is equivalent to column1=column1 which is obviously always true.
http://www.sqlite.org/faq.html#q24
Yes, that's normal in SQL.
Single quotes are used for string values; double quotes are used for identifiers (like table or column names).
(See the documentation.)

Resources