I need to know if it's possible to get all rows from fts table when user doesn't type any text.
I need this, because when app starts, I need to show all rows.
How can I achieve this?
There is no MATCH expression that would return all records.
Just make a special case for the empty string, and use the plain
SELECT * FROM MyTable
Related
I am using this query
"select * from SomeTable group by SomeColumn"
It is returns list with accenting order, but i need to same order like in database.
For example the order in database is:
p
a
s
But result is:
a
i
p
Sample
The result need to be like distinct by CityEN but with all columns and order like 1.Paris 2.Amsterdam 3.Istanbul
In Sqlite, each row of a table has a unique rowid, which you can use for sorting.
select * from SomeTable group by SomeColumn order by rowid;
In your statement, add this line to sort the results:
order by min(rowid)
Your query does not enforce any order with ORDER BY clause so no assumption about row order should be made. If you want specific order add i.e. ORDER BY SomeColumn. See docs about all available order options: https://www.sqlite.org/lang_select.html#orderby
By the rules of SQL, you can't count on getting records back in any specific order without specifying an ORDER BY clause in your SQL query.
In practice servers sometimes return values in the order in which they're inserted, in the order of the first index created, or in the order of the primary key--but you can't count on this behavior, and in fact I've seen the behavior change between database maintenance windows or after the database version is upgraded. You definitely wouldn't want to count on a DB engine to give you back records in any particular order if you write a SELECT statement without an ORDER BY clause.
The only real way to get your records back in the order you inserted them is to create a timestamp column and then sort on it during the SELECT. If you don't want to worry about populating that column on INSERT, have that column auto-populate itself with a timestamp (depending on your DB engine).
I want to perform a query in which the WHERE clausule has the following condition:
one MATCH condition over a column in a FTS3 table
OR
another not MATCH condition over a column in a non FTS table.
Example:
Say that I have two tables
books_fts, which is a table with a content column for full text search.
books_tags, which is non FTS table with tags.
I want to search all the books that either contain 'Dikjstra' in their content or are tagged with the 'algorithm' word. So I run this query:
SELECT * from books_fts
LEFT OUTER JOIN books_tags ON books_fts.fk_id = books_tags.id
WHERE (books_fts MATCH 'content:%Dijkstra*')
OR (books_tags.tag = 'algorithm')
I think the query is right, and if I run it with either one of the OR clausules, it works.
However, when running it with the two clausules I get the following error:
unable to use function MATCH in the requested context
Seems to me that I cannot combine a MATCH with a non MATCH in the WHERE clause, even if each of them apply to different tables (one FTS and another non FTS).
Is this true? I cannot find information on it.
NOTE: if the causules are separated with AND instead of OR the query is valid.
Thanks.
It seems it's a known issue in SQL:
http://sqlite.1065341.n5.nabble.com/FTS3-bug-with-MATCH-plus-OR-td50714.html
I am making a dictionary of over 20,000 words in it. So, to make it work faster when search data, i am using fts3 table to do it.
my select query:
Cursor c=db.rawQuery("Select * from data where Word MATCH '"+word+"*'", null);
Using this query, it will show all the word that contain 'word' , but what i want is to get only the word that contain the beginning of the searching word.
Mean that i want it work like this query:
Cursor c=db.rawQuery("Select * from data where Word like '"+word+"%'", null);
Ex: I have : apple, app, and, book, bad, cat, car.
when I type 'a': i want it to show only: apple, app, and
What can i solve with this?
table(_id primary key not null autoincrement, word text)
FTS table does not use the above attributes. It ignores data type. It does not auto increment columns other than the hidden rowid column. "_id" will not act as a primary key here. Please verify that you are implementing an FTS table
https://www.sqlite.org/fts3.html
a datatype name may be optionally specified for each column. This is
pure syntactic sugar, the supplied typenames are not used by FTS or
the SQLite core for any purpose. The same applies to any constraints
specified along with an FTS column name - they are parsed but not used
or recorded by the system in any way.
As for your original question, match "abc*" already searches from the beginning of the word. For instance match "man*" will not match "woman".
FTS supports searching for the beginning of a string with ^:
SELECT * FROM FtsTable WHERE Word MATCH '^word*'
However, the full-text search index is designed to find words inside larger texts.
If your Word column contains only a single word, your query is more efficient if you use LIKE 'a%' and rely on a normal index.
To allow an index to be used with LIKE, the table column must have TEXT affinity, and the index must be declared as COLLATE NOCASE (because LIKE is not case sensitive):
CREATE TABLE data (
...
Word TEXT,
...
);
CREATE INDEX data_Word_index ON data(Word COLLATE NOCASE);
If you were to use GLOB instead, the index would have to be case sensitive (the default).
You can use EXPLAIN QUERY PLAN to check whether the query uses the index:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM data WHERE Word LIKE 'a%';
0|0|0|SEARCH TABLE data USING INDEX data_Word_index (Word>? AND Word<?)
I've got a fairly complicated query (multiple joins) on a normalized sqlite database. The query does a SELECT * to enable some automated attribute selection logic (so I can't eliminate the "*")
The problem I am having is that my result set contains multiple columns with the same attribute name. For example, one attribute common to each table in the query is "_id". When I go to call "cursor.getColumnIndex("_id")" the value returned is always the index of the last "_id" attribute in the result set column list (i.e. not the one I want). I'd love to be able to use my SQL alias prefixes like cursor.getColumnIndex("A._id") but that is not working.
QUESTIONs
It appears that cursor.getColumnIndex(AttributeName) returns the index of the last "AttributeName". Can anyone confirm this?
Also, any suggestions on how return the index of the 1st attribute with "AttributeName"? or better the Xth attribute having "AttributeName"?
You can do this:
SELECT _id as myID, * FROM myTable
This means the _id field will appear twice for each table in your results, but one of the two columns will have a unique name which should enable you to find it.
Unfortunately the documentation doesn't mention anything about what you need to do, so I am assuming it cannot be done.
However, you say
The query does a SELECT * to enable some automated attribute selection
logic (so I can't eliminate the "*")
What is this 'automated attribute selection logic' you speak of? Why do you require this?
An oder solution is:
"SELECT tableName.columnName FROM tableName"
and then do the same with:
cursor.getColumnIndex("tableName.columnName");
This is what MS-Access does. You can create a query and then see the generated SQL code (simply going to 'view' menu and selecting 'SQL view' from your query dessign window)
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...