Android SQLite additional WHERE condition after MATCH - android

In Android SQLite i got tabel like this
domainObjectId: String // like '9876543210'
name: String
description: String
I want to use FTS on this to search without worrying about diacritical marks, how ever i want to let user select also by typing part of object ID(ex. last 4 char)
I got select like
`SELECT * FROM tabel LEFT JOIN tabel_fts on tabel_fts.domainObjectId = tabel.domainObjectId WHERE tabel_fts MATCH '3210*' OR tabel.domainObjectId LIKE '%3210%'
But in return i get error
unable to use function MATCH in the requested context (code 1 SQLITE_ERROR);
Is this possible to add additional condition to select with MATCH?

Try to remove "MATCH" into separate "SELECT":
`SELECT * FROM tabel LEFT JOIN (select * from tabel_fts WHERE tabel_fts.domainObjectId MATCH '3210*') as tabel_fts WHERE tabel.domainObjectId LIKE '%3210%' OR table_fts.ID IS NOT NULL
By the way:
In your "WHERE tabel_fts" it seemed you've missed a column name
There is no "ON" condition in tables JOINm just "WHERE". That's OK? May be it would be better to use UNION?

Related

How to query in sqlite fts3 table using "-*"?

I have a fts3 table named tab and a lot of entries in it. When I run this query:
SELECT * FROM tab WHERE key MATCH 'an*';
I get the results like this:
an
anul
an-
But when I run this query:
SELECT * FROM tab WHERE key MATCH 'an-*';
it still results the "an" entry. The result would be like:
an
an-
How can I write my query so the result woudn't be "an", but only those entries that actually contains the character "-"?
According to the default tokenizer rules, - separates words, and is otherwise ignored.
You have to search for the word an first, and check for the hyphen afterwards:
SELECT *
FROM tab
WHERE key MATCH 'an'
AND key LIKE 'an-%';

Searching Sqlite Database using Exact Keyword

i`m trying to search a Sqlite Database , with this condition : i want to find a string using an Exact Keyword. let me explain this to you .
i have 3 rows as follow :
catching cold
i have a cat
two cats was seen in your house yesterday
i want to search these rows with keyword "cat" and i expect this result :
i have a cat
i am using this SQL code so far :
Select * FROM MyTable WHERE Mycolumn Like '%cat%'
But Returning Result is All these 3 Rows:
catching cold
i have a cat
two cats was seen in your house yesterday
What can i do to get my expected result?
thank you in advance.
The % character in the argument of a LIKE clause matches any string, including the empty string. Unfortunately, SQLite doesn't have the REGEXP function built in (and Android's SQLite doesn't have it).
What you can do instead is use FTS (full text search). How to do so is described here: https://www.sqlite.org/fts3.html#section_1_2
Using your example, you would set it up like so:
create virtual table textsearch using fts4(content);
insert into textsearch (content) values ('catching cold'), ('i have a cat'), ('two cats was seen in your house yesterday')
Then you can do a simple text query with the MATCH operator:
select * from textsearch where content match 'cat';
If you try the above in a sqlite3 shell, you'll see it returns only 'i have a cat'. There's a lot more you can do with the match operator, explained on the page I linked above.
You can use a regular expression with a special pattern for word boundaries.
Select * FROM MyTable WHERE Mycolumn = 'cat'
Corrected my answer i think that should work.

Search String in column value of Sqlite

I am trying to search a String in column of my table .The values are stored in
column in this format
My Search String is similar as above. i.e: comma separated String
My query is to find out whether any value in search String is present is my column or not.
Things I have Tried:
using Like : Like does it.But it matches individual values i.e for 3 search string values I have to make 15 like condition(costly for large table)
SELECT * from A WHERE mycol LIKE 'myval,%' or mycol LIKE '%, myval,%' or mycol or LIKE '%, myval'
using instr function : instr matches the String but only the First Occurance.
e.g: select * from A where instr ('123' ,'12')
using In : This donot search within the String .But Matches the values individually.
I have tried Like function Like(X , Y) from docs Here
So my Question is there a way , instead of Individually searching my search string in the column using Like Operator or In function . I could search my values values in single query something like combination of In and Any(not supported in Sqlite) function does in other Db
i.e select * from A where Any('my search string') in ('my column value')
Any Answer or comment is HIGHLY Appreciated.Hoping for reply.
You have problems because your database is not properly normalized.
To have multiple search IDs for each MyTable row, create a second table that can have multiple rows, with one search ID in each row:
CREATE TABLE MyTable (
MyTableID INTEGER PRIMARY KEY,
[...]
);
CREATE TABLE MyTableSearchIDs (
MyTableID INTEGER REFERENCES MyTable(MyTableID),
SearchID INTEGER -- or TEXT or whatever
);
To search for a MyTable row, search its ID first:
SELECT *
FROM MyTable
WHERE MyTableID IN (SELECT MyTableID
FROM MyTableSearchIDs
WHERE SearchID = 'myvalue')
The same can be done with a join:
SELECT MyTable.*
FROM MyTable
JOIN MyTableSearchIDs USING (MyTableID)
WHERE MyTableSearchIDs.SearchID = 'myvalue'

SQL select specific fields in JOIN query

i'm writing an Android app and i've run into a bit of a roadblock involving databases. the way Android handles databases, i cannot refer to names in the result set by the usual 'tablename.colname' method, so this presents a huge issue when any tables in the database contain the same column name. what further complicates the issue, is that any table that is used by a ViewAdapter to display the data to the user (as in my application), must contain a field named "_id" as an autoincrement primary key int. therefore, some tables MUST have identical column names. however, to avoid this, it is possible to use an "AS" clause in a statement to rename the value in question. however, i'm using a rather long statement and i don't know how to limit the columns returned on a JOINed table. what i have is this, and it's completely illegal in android due to the 'tablename.colname' references. i actually added the table names in to make the statement more readable, but i can't use them:
SELECT call._id AS android_call_id,
call.phone,
call.time,
call.duration
call.duration_billed
call.pending
call.call_id
call.job_id
FROM call
LEFT OUTER JOIN phone ON call.phone_number=phone.phone
LEFT OUTER JOIN job ON job._id=call.job_id
WHERE call.pending=1 ORDER BY job._id
but what i need, is to rename the job._id to something else using an "AS" statement, same as with the 'call._id' field in the first part of the query. how do i achieve this renaming in a JOIN?
edit:
progress so far. i think i've worked out the syntax errors, but i get another runtime error "no such column 'job._id', which may be related to #Tom H. comment
edit 2:
turns out Tom was right, and i adjusted accordingly, but it doesn't work:
SELECT call._id AS android_call_id,
call.phone,
call.time,
call.duration,
call.duration_billed,
call.pending,
call.call_id,
call.job_id,
job._id AS android_job_id,
job.job_name,
job.job_number
FROM call
LEFT OUTER JOIN phone ON call.phone_number=phone.phone
LEFT OUTER JOIN job ON job._id=call.job_id
WHERE call.pending=1 ORDER BY job._id
error:
05-24 16:50:37.561: ERROR/Minutemaid - Service(7705): oops: ambiguous column name: call._id: , while compiling: SELECT call._id AS android_call_id,call.phone_number,call.time,call.duration,call.duration_billed,call.pending,call.call_id,call.job_id,job._id AS android_job_id,job.job_name,job.job_number FROM call LEFT OUTER JOIN phone ON call.phone_number=phone.phone LEFT OUTER JOIN call ON call.job_id=job._id WHERE call.pending=1 ORDER BY job._id
Can't you simply use AS to alias all of the tablename.columnname references to unique names in the result set?
You can simply create a VIEW that restricts columns selectable in a table and assigns another name to them.
You can try massaging the table names before you join them by using sub-queries with AS in the FROM clause. For example:
select c_phone, c_id, p_id
from (select id as c_id, phone as c_phone, phone_number as c_phone_number, ... from call) as c
left outer join (select id as p_id, phone as p_phone, ... ) as p
on c_phone_number = p_phone
...
If the limitation is just that you can't use table names to distinguish between columns but can use correlation names then simpler is:
select c.id, c.phone, p.id as "p_id" from ... call c join phone p

How to query similar records in SQLite database from Android?

Let's say an SQLite database column contains the following value:
U Walther-Schreiber-Platz
Using a query I'd like to find this record, or any similar records, if the user searches for the following strings:
walther schreiber
u walther
walther-schreiber platz
[Any other similar strings]
However I cannot figure out any query which would do that. Especially if the user does not enter the - character.
Example:
select * from myTable where value like '%walther schreiber%'; would not return the result because of the missing -.
Thanks,
Robert
So, as I said in my comment, I think you can have a query along the lines of:
select * from myTable where LOWER(value) like <SearchValue>
I'm assuming you're collecting the <SearchValue> from the user programmatically, so would be able to do the following: <SearchValue> would need to be: The user's search string, appropriately cleansed to avoid SQL injection attacks, converted to lower case, with all of the spaces converted to '%', so that they match zero or more characters...
So you would have (for example):
select * from myTable where LOWER(value) like '%walther%schreiber%'
select * from myTable where LOWER(value) like '%walther-schreiber%platz%'
etc... however, this does assume that the word order is the same, which in your examples it is...

Categories

Resources