Sqlite statement match exact string iphone - iphone

I have the following words in table database:
name id
aba 0
abac 1
abaca 2
abace 3
I want to make the following select:
Select id from words where name='abaca';
I tried but it doesn't work. I want the exact match of the word I'm entering to match.

I tried with your entries and following query does work perfectly fine for an Exact match
SELECT * FROM Match WHERE title='abaca';
Where Match is the table name with following schema
CREATE TABLE Match (title text,recordId integer)
Following is the record inserted
Though I made the same mistake by Taking Match as Table name as you did by taking id as the column name, but I only realized it while posting the code. But that should really not make much difference here.
Have you used it in some code to fetch result from database? in case yes you should consider avoiding KEYWORDS as variable,column names.. Just a suggestion.

Related

Sphinx - How to get an Exact Match, i.e. same as mysql WHERE column = "value"

I've got a real time index containing information on people (a definition is included below). The problem is that I'm trying to run an exact match on a phone number and email address and no matter what I try, I'm getting matches even if the database column values contains what I've searched for, not where the column value exactly matches.
The query I'm using is:
SELECT id, first_name,last_name,email_personal, phone_number, WEIGHT() as relevance FROM people WHERE MATCH('#(phone_number,email_personal) "^+447111$" "^myemail#gmail\.com$ "');
That returns rows that contains a full phone number (i.e. +44711122334), as far as I understand it, shouldn't, it should be trying to match "^+447111$" as the start & end of the field?
I've also tried this test query and have much the same issue, apart from the fact it returns a lot more matches, as it would do it was matching any of the field values containing the criteria, rather than the whole field value. The values aren't the full values I'm looking for, but this is a test as it should be matching rows that only have a phone number of "+447711" and email of "#gmail.com", which don't exist in the database, but it does return rows, where the phone number starts with +447711 and the email has #gmail.com in it.
SELECT id, first_name,last_name,email_personal,phone_number, WEIGHT() as relevance FROM people WHERE MATCH('#phone_number "^+447711$" #email_personal "^#gmail\.co$"') ORDER BY relevance DESC;
Just to confirm, I'm trying to find matches where the values of the fields match the exact text, i.e. this would be the SQL query (and yes, this doesn't work either!)
SELECT id,first_name,last_name,email_personal,phone_number FROM people WHERE phone_number = '+44711122334' AND email_personal = 'myemail#gmail.com';
Config:
index people
{
type = rt
path = /var/local/sphinx/indexes/ppl/
rt_field = first_name
rt_field = last_name
rt_field = phone_number
rt_field = email_personal
stored_fields = first_name,last_name,phone_number,email_personal
rt_mem_limit = 512M
expand_keywords = 1
min_prefix_len = 2
min_word_len = 2
index_exact_words = 1
}
bah! This is always the way. You spend hours trying to figure it out, post it to StackOverflow and then within a few moments the answer jumps out at you.
It turns out it was the 'expand_keywords' setting in the config that was responsible. For those who don't know, this is what it does...
Queries against indexes with expand_keywords feature enabled are internally expanded as follows. If the index was built with prefix or infix indexing enabled, every keyword gets internally replaced with a disjunction of keyword itself and a respective prefix or infix (keyword with stars). If the index was built with both stemming and index_exact_words enabled, exact form is also added. Here's an example that shows how internal expansion works when all of the above (infixes, stemming, and exact words) are combined:
running -> ( running | *running* | =running )
So that despite trying to search for exact matches, that was causing it to always expand and search for the text within the column, not that the column exactly matched.
Taking that line out of the config & restarting Sphinx solved the issue straight away, you don't even need to re-index, which is good.
I thought I'd leave the question and answer here incase anyone else has a similar "issue" ;)

Trying different functions

in the first function, I'm making the job column lowercase and then searching through but it's not finding any data. Why? Thanks. Just FYI since you don't have the database, all records in the JOB column are uppercase (that's why isn't returning anything), but that's also why I'm making it lowercase first.
In the second function, I'm trying to concat only ename with specific criteria --anything that has an r in the ENAME column (there are multiple records with the r in it), but isn't working (no data found), why? How do I get it done? Thanks.
SELECT LOWER(JOB) FROM EMP
WHERE JOB = LOWER('MANAGER');
SELECT CONCAT('My name is ',ename)
FROM EMP
WHERE ENAME LIKE '%r%';
I tested both of your SQL statements and they work fine for me. Are you sure the records are in db? Are you sure the names of the rows are correct?
EDIT : OK, so the name of column is in lower case but in your WHERE its in uppercase. Thats all :)

Efficient way to find ordered string's exact, prefix and postfix match in PostgreSQL

Given a table name table and a string column named column, I want to search for the word word in that column in the following way: exact matches be on top, followed by prefix matches and finally postfix matches.
Currently I got the following solutions:
Solution 1:
select column
from (select column,
case
when column like 'word' then 1
when column like 'word%' then 2
when column like '%word' then 3
end as rank
from table) as ranked
where rank is not null
order by rank;
Solution 2:
select column
from table
where column like 'word'
or column like 'word%'
or column like '%word'
order by case
when column like 'word' then 1
when column like 'word%' then 2
when column like '%word' then 3
end;
Now my question is which one of the two solutions are more efficient or better yet, is there a solution better than both of them?
Your 2nd solution looks simpler for the planner to optimize, but it is possible that the first one gets the same plan as well.
For the Where, is not needed as it is covered by ; it might confuse the DB to do 2 checks instead of one.
But the biggest problem is the third one as this has no way to be optimized by an index.
So either way, PostgreSQL is going to scan your full table and manually extract the matches. This is going to be slow for 20,000 rows or more.
I recommend you to explore fuzzy string matching and full text search; looks like that is what you're trying to emulate.
Even if you don't want the full power of FTS or fuzzy string matching, you definitely should add the extension "pgtrgm", as it will enable you to add a GIN index on the column that will speedup LIKE '%word' searches.
https://www.postgresql.org/docs/current/pgtrgm.html
And seriously, have a look to FTS. It does provide ranking. If your requirements are strict to what you described, you can still perform the FTS query to "prefilter" and then apply this logic afterwards.
There are tons of introduction articles to PostgreSQL FTS, here's one:
https://www.compose.com/articles/mastering-postgresql-tools-full-text-search-and-phrase-search/
And even I wrote a post recently when I added FTS search to my site:
https://deavid.wordpress.com/2019/05/28/sedice-adding-fts-with-postgresql-was-really-easy/

Return rows where words match in two columns OR in match in one column and the other column is empty?

This is a follow-up to another question I recently asked.
I currently have a SphinxQL query like this:
SELECT * FROM my_index
WHERE MATCH(\'#field1 "a few words"/1 #field2 "more text here"/1\')
However, I would still like it to match rows in the case where one of the fields in the row is empty.
For example, let's say the following rows exist in the database:
field1 | field2
-----------------------
words in here | text in here
| text in here
The above query would match the first row, but it would not match the second row because the quorum operator specifies that there has to be one or more matches for each field.
Is what I'm asking possible?
The actual query I'm trying to make this work with was provided in Barry Hunter's answer to my previous question:
sphinxQL> SELECT *, WEIGHT() AS w FROM index
WHERE MATCH('#tags "cute hairy happy"/1 #tags2 "one two thee"/1') AND w = 2
OPTION ranker=expr('SUM(IF(word_count>=IF(user_weight=2,tags2_len,tags_len),1,0))'),
field_weights=(tags=1,tags2=2);
First problem is sphinx doesn't index "empty" so you can't search for it. (well actually the field_len attribute will be zero. But it can be hard to combine attribute filter with MATCH())
... so arrange for empty to be something to index
sql_query = SELECT id,...,IF(tags='','_empty_',tags) AS tags FROM ...
Then modify the query. As it happens your quorum search is easy!
#field1 "a few words _empty_"/1
Its just another word. But a more complex query would just have to be OR'ed with the word.
Then there is making it work within your complex query. But as luck would have it, its really easy. _empty_ is just another word. And in the case of the field being empty, one word will match. (ie there are no words in the field, not in the query)
So just add _empty_ into the two quorums and you done!

SELECT query in PostgreSQL

I am trying to retrieve values from a PostgreSQL database in a variable using a WHERE clause, but I am getting an error.
The query is:
select age into x from employee where name=name.GetValue()
name is the textcontrol in which I am entering a value from wxpython GUI.
I am getting an error as name schema doesn't exist.
What is the correct method for retrieving values?
"name.GetValue()" is a literal string, you are sending that to your db which knows nothing about wxpython and nothing about the variables in your program. You need to send the value of that data to your db, probably using bound parameters. Something like:
cur.execute("select age from employee where name=%s", [name.GetValue()])
x = cur.fetchone()[0] # returns a row containing [age] from the db
is probably what you're after. This will create a query with a placeholder in the database, then bind the value of name.GetValue() to that placeholder and execute the query. The next line fetches the first row of the result of the query and assigns x to the first item in that row.
I'm not positive what you are trying to do, but I think your issue might be syntax (misuse of INTO instead of AS):
SELECT age AS x FROM employee WHERE name = ....