SQLITE EXCEPT on a single column - sqlite

I've got two sub-queries on a table, and I want the result to be similar to
SELECT * FROM table WHERE condition1
EXCEPT
SELECT * FROM table WHERE condition2;
However, I only want a single column to be considered for the purpose of this set operation, because the other columns are always different. Thus, the above query always returns everything in the first set, instead of only those elements which don't appear in the second set (comparing only a single column).
If I was trying to find the UNION I could do it with a JOIN, but since I'm trying to find the complement instead I'm not sure the way to go about doing this.

SELECT *
FROM table
WHERE condition1
AND someColumn NOT IN (SELECT someColumn
FROM table
WHERE condition2)

Related

SQLite: How to UPDATE column using count(*) range?

I'm not sure I'm using right terminology here.
Basically I want to update entire "id" column using count(*) [485] as a delimiter, in an ascending order, so the resulting row value will correspond with rownumber (not the rowid).
If I understand you correctly, this should work for you:
UPDATE tbl_name SET id=rowid
EDIT
If that's is the case -> then it's a lit bit more tricky, since SQlite doesn't support variables declaration.
So what I suggest is,
To create temporary table from select of your original table which makes it's rowids to be as row numbers 1,2,3 etc...
Set it's rowNum (the needed row number column) as each rowid
Then replace the original table with it.
Like this: (assume original table called orig_name)
CREATE TABLE tmp_tbl AS SELECT rowNum FROM orig_name;
UPDATE tmp_tbl SET rowNum=rowid;
DROP TABLE orig_name;
CREATE TABLE orig_name AS SELECT rowNum FROM tmp_tbl;
DROP TABLE tmp_tbl;
Try this: http://www.sqlite.org/lang_createtable.html#rowid
You can use some inner database variables such as rowid, oid etc to get what you need.
[edit]
Think I just understood what you meant, you want for each insert action, add a value that is the total count of rows currently in the table?
If so, try something like this:
UPDATE tbl_name
SET id = (select count(*) from tbl_name)
WHERE yada_yada_yada

Insert into SQLite3 into "middle" of table

I just want to clarify: if you insert a row to a table in sqlite, it appends it to the table, but -- as I learned -- the table is unordered, so there is really not true way to insert a row into the middle of an "ordered table," right?
Is there even a way to make an ordered table without first created a table and then using '...ORDER BY name/id/etc' (i.e. when you insert something it puts itself in the right place)?
SQLite tables are actually stored in rowid order, but this is unlikely to help you because it is unlikely that there is a gap where you want it.
Furthermore, the order in which rows are stored does not matter because there is no guarantee that this is the order in which they are returned.
When you want to SELECT rows in a specific order, you must use ORDER BY.
If your query is too slow, an index on the sorting column might help.

Getting a range of tuples from an ordered SQLite table

First I'd like to apologize if the topic seems vague; I always have a hard time framing them succinctly. That done, I'll get into it.
Suppose I have a database table that looks like the following:
CREATE TABLE The_table(
item_id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
item TEXT);
Now, I have a pretty basic query that will get items from said table and order them:
SELECT *
FROM The_table
ORDER BY x;
where x could be either item_id or item. I can guarantee that both fields are order-able. My question is this:
Is there a way to modify the query I gave to get a range of the ordered elements: say from 20th element in the table to the 40th element in the table (after the table has been ordered) or something similar.
Any help would be appreciated.
Thanks,
Yes - it's called "between"
SELECT *
FROM The_Table
WHERE item_id BETWEEN 20 AND 40
This does exactly what it says - it looks for a value between the two numbers supplied. Very useful for finding ranges; works in reverse too (i.e. NOT BETWEEN). For more see here.
If you want a specific row or group of rows (as your updated question suggests) after sorting you can use the LIMIT clause to select a range of entries
SELECT *
FROM The_Table
LIMIT 20, 20
Using LIMIT this way the first number is the starting point in the table and the second number is how many records to return from that point. This statement will return 20 rows starting at row 20 whatever that value is.

Selecting unique rows from a table that are not found in two other tables in sqlite

I have three tables (forward, reverse and probe) that all contain the same columns (Query, QueryLength, Hit, Start, End, Strand, Description, Length, Percent_id, Score, Evalue).
I want to get the unique rows from 'forward' where the 'Hit' is not found in either the 'reverse' table or the 'probe' table. With 'AND' I don't get any results, with 'OR' I get the comparison only with reverse.
CREATE TABLE f AS SELECT * FROM forward WHERE forward.Hit NOT IN (SELECT Hit from reverse) OR (SELECT Hit FROM probe)
Thanks for your help.
When you write ... OR (SELECT Hit FROM probe), you have a scalar subquery, i.e., the database looks only at the first value returned by the subquery, and treats it as 'true' if the value is non-zero.
To check whether a value is found in another table, you have to use IN (in both cases):
SELECT * FROM forward
WHERE Hit NOT IN (SELECT Hit FROM reverse)
AND Hit NOT IN (SELECT Hit FROM probe)
If you want to check entire records instead of only one column, you can use EXCEPT:
SELECT * FROM forward
EXCEPT
SELECT * FROM reverse
EXCEPT
SELECT * FROM probe

How can I insert a new table row into every other row in an existing table?

Ok I have a sqlite db, that has roughly 100 rows. It is kind of a strange thing that I'm trying to do, but I need to insert a new row between each of the existing rows.
I have been trying to use the Insert statement as follows, but haven't had any luck:
insert into t1(column1) values("hello") where id%2 == 0
So I'm basically trying to use the %-operator to tell me if the id is even or odd. For every even id number, I'd like to insert a new row.
What am I missing? What can I do differently? How can I insert a new row into every other row and have the index updated as well?
Thanks
Your question assumes that the rows have some kind of built-in order to them, and that you can insert rows between other rows. That's not true.
It is true that rows have an order on disk, and that the id column is usually assigned in order, but that's an implementation detail. When you perform a query, the database is free to return the rows in any order it chooses, unless you specify what you want with an ORDER BY clause.
Now, I'm assuming what you really want is to insert rows between the existing rows in id order. One way to get what you want would look like this:
UPDATE t1 SET id = id * 2
INSERT INTO t1 (id, column) SELECT id+1, "hello" FROM t1
The UPDATE would double the ids of all the existing rows (so 1,2,3 becomes 2,4,6); then the INSERT would perform a query on t1 and use the result to insert a new set of rows with id values one more than the existing rows (so 2,4,6 becomes 3,5,7).
I haven't tested the above statements, so I don't know if they would work or if they require some extra trickery (like a temporary table) since we are querying and updating the same table in one statement. Also I may have made a syntax error.
Don't consider the rows as pre-ordered in the database. A database will store them as they come in, or according to an index. It's your task to order them on retrieval (i.e. when you query for data) according to your needs.

Resources