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

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.

Related

select * from (select...) sqlite python

I'm working on a sqlite database and try to make a special request between two tables.
In the first table (table1 for example), i have two columns named "reference" and "ID". I want to search an ID in it, get it value in "reference" and display all informations from the table which have this value as name.
I try to find something on the internet but I didn't find an answer.
This is the request I made:
select * from (select Reference from table1 where Name='Value1')
It only give me the result of
select Reference from table1 where Name='Value1'
EDIT:
I want
select Reference from table1 where Name='Value1' => name of table
select * from name of table => show all elements
I'm new in sqlite but I hope you can help me.
Thank you by advance
Matt
If I understand your question correctly, I don't think there's a way to do it in sql completely (or at least not in a portable way). I'd recommend one of 3 solutions:
Do exactly what you want, but do some processing in Python. That means query your master table, then construct new query based on each of the rows returned.
If you have many tables, possibly changing dynamically - it may be a good idea to rethink your database design. Maybe you can move some of the changing table names into a new column and put your data in one table?
If you have only a few tables available as the Reference and they never change, you could join all the possible tables, like:
SELECT ... FROM table1
LEFT JOIN table2
ON table1.id = table2.id AND table1.Reference = "table2"
LEFT JOIN table3 ...
But you may need to explain it all a bit better...

Joining tables in SQLite - what and how?

I need to manipulate some data in SQLite, it should be simple but trying to figure it out how to do exactly this has frustrated me.
It's just a join, one table called "routes" has a column "stop_id". I need to take another table called "stops" which also has a "stop_id" column and everywhere that they match, add all the additional columns from "stops" to the "routes" table (added columns are "stop_name" "stop_lat" "stop_lon" and "master_station"). "stop_id" is the primary key in the stops table. I need to join the tables and not keep them relational because after I do that I will be changing the rows by hand with new information. I am using Firefox SQLite Manager if that matters.
A join can be done with JOIN:
SELECT * FROM routes JOIN stops USING (stop_id)
However, the result of a join cannot be changed directly; the UPDATE statement works only on actual tables.
To change values that come from the routes or stops tables, you have to update those tables by using their respective primary keys to look up the records.

sqlite full text wild card search

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

SQLite: JOIN back INTO left table?

If I have this statement,
SELECT table1.*, table2_1.`values` AS val_1
FROM table1 JOIN table2_1
ON table1.row_names=table2_1.row_names
I would actually like this the result joined back into table1. Any inclusion of a join statement after SELECT and before FROM gives me an error.
Why can I not save the results to a table, and is it possible to save it back to one of the original tables?
Because you do it the wrong way. SELECT statement will not modify you data no matter how much you want it. If you want to modify data, you need to use UPDATE statement.

Deleting rows from SQLite table when no match exists in another table

I need to delete rows from an SQLite table where their row IDs do not exist in another table. The SELECT statement returns the correct rows:
SELECT * FROM cache LEFT JOIN main ON cache.id=main.id WHERE main.id IS NULL;
However, the delete statement generates an error from SQLIte:
DELETE FROM cache LEFT JOIN main ON cache.id=main.id WHERE main.id IS NULL;
The error is: SQLite Error 1 - near "left": syntax error. Is there another syntax I could use?
SQLite apparently doesn't support joins with the delete statement, as you can see on the Syntax diagrams. You should however be able to use a subquery to delete them.
ie.
DELETE FROM cache WHERE id IN
(SELECT cache.id FROM cache LEFT JOIN main ON cache.id=main.id WHERE main.id IS NULL);
(Not tested)
Since you going down the route of subquery, might as well get rid of the join altogether and simplify the query:
DELETE FROM cache WHERE id NOT IN (SELECT id from main);
Solution from #wimvds didn't work for me, so I modified the query and removed WHERE condition:
DELETE FROM FirstTable WHERE firstTableId NOT IN (SELECT SecondTable.firstTableId FROM SecondTable LEFT JOIN FirstTable ON FirstTable.firstTableId=SecondTable.firstTableId)
This deletes all the rows from FirstTable that do not have their id assigned to any row in SecondTable.

Resources