sqlite full text wild card search - sqlite

Can Sqlite FT3 or FT4 do something like
SELECT * FROM MyTable WHERE body MATCH '*qlite'
I know this:
SELECT * FROM MyTable WHERE body MATCH 'Sqlite*'
works but seems like '%like' like operation doesn't work in the full text.

From what I understand it's a limitation of FTS in general, across platforms, that suffix/postfix searches aren't possible.
The best workaround I've seen is to add a column to MyTable called ReverseBody and store the reverse of the Body column in there and add it to the FT index as well. Then you write queries like
select * from MyTable where reversebody match (REVERSE('qlite') + '*')
I work in SQL Server so we have a REVERSE built in. I don't think SQLite does, but you can add custom functions to do it as descrbed here

Related

Is it possible to select a field from a table, but override it with a new value in the select statement?

I am creating a view like this:
Let's say I originally have this:
select * from mydb.mytable
mydb.mytable has a field called FirstName, but I want to transform its value in the select statement. Conceptually, I want to do this:
select *, upper(firstname) firstname from mydb.mytable
The problem is that * is already returning FirstName, so adding another column of the same name to the select breaks the SQL. To get it to work, I have to list each field like this:
select upper(firstname) firstname, lastname, city, state, zip
This is just one example, but the table I really want to use this with has 30+ columns. I don't like the idea of having to list out each column because adding a new field to the table means I have to modify the SQL (ordinal field position doesn't matter).
Well, that's the way SQL is designed, it's not a specific Teradata problem.
You want something like "select * but firstname" and no DBMS has implemented such a syntax.
Btw, one of (my) basic SQL rules is: never write "SELECT *" :-)
As dnoeth says, that's just how SQL works. Also, I'd reinforce his comment about never using select *, especially in a view.
To address concerns like this, I keep the table and view DDL together in code. Whenever you change the table definition, you change the view definition at the same time. That way, whenever you add or remove columns from your table (your stated concern), your view always remains current.

Searching middle part of the string using Full Text Search in sql server

I am not able to search the middle part of string using fulltext search index for eg:there was a string "I like music" i was not able to search for like which is in the middle part of string..
Try LIKE operator.
SELECT
*
FROM
YourTABLE
WHERE
ColumnName LIKE '%like%'
Use Like keyword in query as follows:
select * from tablename where col like '%like%'
Here is the tutorial of like in sql:
http://www.w3schools.com/sql/sql_like.asp
Here is the MSDN:
http://msdn.microsoft.com/en-us/library/ms179859.aspx
Hope its helpful.
Well, in order to still use the fulltext index and to avoid a table scan, try this
select *
from yourTable
where contains (ColumnName,'like')
and (ColumnName not like 'like%' or ColumnName like '_%like%')
However, the query optimizer might decide that a full table scan is more effective.
Check if statistics of your table out of date, especially check the statistics relates to your fulltext index. Since you are using SQl Server 2008, so, you can query DMV to get statistics information of your index or using DBCC to see the statistics detail information
DBCC SHOW_STATISTICS ("[schema].[table]",indexname);
Check the first return result, [Updated], [rows], [rows sampled], if the statistics out of date, or [rows sampled] far less than [rows], which many cause SQL Engine decided to use table scan instead of using your index.

Why does SQLite's LIKE% not work in a JOIN?

Using the Chinook test database, the following SQL statement works in SQLite:
SELECT * FROM playlist WHERE Name LIKE '%the%'
Yet if I use JOINs:
SELECT * FROM playlist AS pl
JOIN playlisttrack AS plt ON pl.PlaylistId=plt.PlaylistId
JOIN track AS t ON plt.TrackId=t.TrackId WHERE pl.Name LIKE '%the%'
SQLite fails on the WHERE statement, although MySQL works fine:
What makes SQLite fail here?
Are you sure you have playlisttrack and track for your playlist?
Replace JOIN by LEFT JOIN to get all playlist even if they don't have playlisttrack or track
The LIKE seems to work, as you get the same result.
The problem seems to be multiple columns with the name "Name" in the three tables. I would avoid "SELECT *" and select the columns you need instead, using aliases to make clear what is what.

sqlite Query optimisation

The query
SELECT * FROM Table WHERE Path LIKE 'geo-Africa-Egypt-%'
can be optimized as:
SELECT * FROM Table WHERE Path >= 'geo-Africa-Egypt-' AND Path < 'geo-Africa-Egypt-zzz'
But how can be this done:
select * from foodDb where Food LIKE '%apples%";
how this can be optimized?
One option is redundant data. If you're querying a lot for some fixed set of strings occuring in the middle of some column, add another column that contains the information whether a particular string can be found in the other column.
Another option, for arbitrary but still tokenizable strings is to create a dictionary table where you have the tokens (e.g. apples) and foreign key references to the actual table where the token occurs.
In general, sqlite is by design not very good at full text searches.
It would surprise me if it was faster, but you could try GLOB instead of LIKE and compare;
SELECT * FROM foodDb WHERE Food GLOB '*apples*';

SQL Server 2005 - Pass In Name of Table to be Queried via Parameter

Here's the situation. Due to the design of the database I have to work with, I need to write a stored procedure in such a way that I can pass in the name of the table to be queried against if at all possible. The program in question does its processing by jobs, and each job gets its own table created in the database, IE table-jobid1, table-jobid2, table-jobid3, etc. Unfortunately, there's nothing I can do about this design - I'm stuck with it.
However, now, I need to do data mining against these individualized tables. I'd like to avoid doing the SQL in the code files at all costs if possible. Ideally, I'd like to have a stored procedure similar to:
SELECT *
FROM #TableName AS tbl
WHERE #Filter
Is this even possible in SQL Server 2005? Any help or suggestions would be greatly appreciated. Alternate ways to keep the SQL out of the code behind would be welcome too, if this isn't possible.
Thanks for your time.
best solution I can think of is to build your sql in the stored proc such as:
#query = 'SELECT * FROM ' + #TableName + ' as tbl WHERE ' + #Filter
exec(#query)
not an ideal solution probably, but it works.
The best answer I can think of is to build a view that unions all the tables together, with an id column in the view telling you where the data in the view came from. Then you can simply pass that id into a stored proc which will go against the view. This is assuming that the tables you are looking at all have identical schema.
example:
create view test1 as
select * , 'tbl1' as src
from job-1
union all
select * , 'tbl2' as src
from job-2
union all
select * , 'tbl3' as src
from job-3
Now you can select * from test1 where src = 'tbl3' and you will only get records from the table job-3
This would be a meaningless stored proc. Select from some table using some parameters? You are basically defining the entire query again in whatever you are using to call this proc, so you may as well generate the sql yourself.
the only reason I would do a dynamic sql writing proc is if you want to do something that you can change without redeploying your codebase.
But, in this case, you are just SELECT *'ing. You can't define the columns, where clause, or order by differently since you are trying to use it for multiple tables, so there is no meaningful change you could make to it.
In short: it's not even worth doing. Just slop down your table specific sprocs or write your sql in strings (but make sure it's parameterized) in your code.

Resources