How do I use two sql syntax keywords - sqlite

I have a sqlite database with a column named 'name'.
The name column contains 30 rows.
5 are populated with data and 25 give a null value.
I am trying to get sqlite to return only populated rows AND then order by asc.
I thought it be as easy as
SELECT * FROM students
WHERE name IS NOT NULL AND ORDER BY name ASC.
But I was wrong.
Any idea's?
Thanks

SELECT * FROM students WHERE name IS NOT NULL ORDER BY name ASC.
omit the AND.

Related

Sqlite INSERT INTO ... SELECT using ORDER BY

I have a table as below:
CREATE TABLE IF NOT EXISTS TRACE_TABLE ([TRACE_NUM] INTEGER NOT NULL PRIMARY KEY [TRACE_ID] INTEGER NOT NULL [TRACE_TIME_DELTA] TEXT NOT NULL [TRACE_TIME_HEX] INTEGER NOT NULL [TRACE_TIME_AHB] INTEGER NOT NULL [TRACE_PARAM_TEXT] TEXT NOT NULL [TRACE_PARAM_TEXT_DECODED] TEXT);
Now I want to sort this table using a column. To do this I do following:
Create a new table TRACE_TABLE_TEMP using above statement if not exists.
Then delete all rows (in case any exists) by earlier operations
Then copy all rows from TRACE_TABLE to TRACE_TABLE_TEMP but in sorted order using a column.
I try to execute the statement in Sqlite DB browser but I am not getting the expected result. Please see below, the TRACE_NUM column is not sorted as DESC.
How do I copy the table to another in sorted order?
The documentation says:
If a SELECT statement that returns more than one row does not have an ORDER BY clause, the order in which the rows are returned is undefined.
So it does not make much sense to change the order in which rows are stored, because you'd have to put the same ORDER BY on the queries used to read the data later.
Anyway, the error is that 'TRACE_NUM' is a constant string. To refer to the contents of the column, use TRACE_NUM.

Copy rows from table to another

I want to copy the rows of a table OLD into another table NEW.
INSERT INTO NEW
SELECT date, kind, id, product, version, quantity FROM OLD;
The table OLD has a column kind which is VARCHAR and contains words like insert, extract, delete. In the NEW table this column is an INTEGER. Is there a way to say that if you find delete insert 1, if you find extract insert 2 etc.. ?
This should work for you,
INSERT INTO Destination SELECT * FROM Source;
See SQL As Understood By SQLite: INSERT for a formal definition.
You can use a CASE statement to replace the string labels with integers:
INSERT INTO NEW
SELECT date,
CASE WHEN kind = 'delete' THEN 1
WHEN kind = 'extract' THEN 2
ELSE ...
END,
product,
version,
quantity
FROM OLD;
This assumes that the columns line up correctly, and all the other column types match.

Make select query return in order of arguments

I have a relatively simple select query which asks for rows by an column value (this is not controlled by me). I pass in a variable argument of id values to be returned. Here's an example:
select * from team where id in (2, 1, 3)
I'm noticing that as the database changes its order over time, my results are changing order as well. Is there a way to make SQLite guarantee results in the same order as the arguments?
If you could have so many IDs that the query becomes unwieldy, use a temporary table to store them:
CREATE TEMPORARY TABLE SearchIDs (
ID,
OrderNr INTEGER PRIMARY KEY
);
(The OrderNr column is autoincrementing so that it automatically gets proper values when you insert values.)
To do the search, you have to fill this table:
INSERT INTO SearchIDs(ID) VALUES (2), (1), (3) ... ;
SELECT Team.*
FROM Team
JOIN SearchIDs USING (ID)
ORDER BY SearchIDs.OrderNr;
DELETE FROM SearchIDs;
Try this!
select * from team order by
case when 2 then 0
when 1 then 1
when 3 then 2
end

How do I find out if a SQLite index is unique? (With SQL)

I want to find out, with an SQL query, whether an index is UNIQUE or not. I'm using SQLite 3.
I have tried two approaches:
SELECT * FROM sqlite_master WHERE name = 'sqlite_autoindex_user_1'
This returns information about the index ("type", "name", "tbl_name", "rootpage" and "sql"). Note that the sql column is empty when the index is automatically created by SQLite.
PRAGMA index_info(sqlite_autoindex_user_1);
This returns the columns in the index ("seqno", "cid" and "name").
Any other suggestions?
Edit: The above example is for an auto-generated index, but my question is about indexes in general. For example, I can create an index with "CREATE UNIQUE INDEX index1 ON visit (user, date)". It seems no SQL command will show if my new index is UNIQUE or not.
PRAGMA INDEX_LIST('table_name');
Returns a table with 3 columns:
seq Unique numeric ID of index
name Name of the index
unique Uniqueness flag (nonzero if UNIQUE index.)
Edit
Since SQLite 3.16.0 you can also use table-valued pragma functions which have the advantage that you can JOIN them to search for a specific table and column. See #mike-scotty's answer.
Since noone's come up with a good answer, I think the best solution is this:
If the index starts with "sqlite_autoindex", it is an auto-generated index for a single UNIQUE column
Otherwise, look for the UNIQUE keyword in the sql column in the table sqlite_master, with something like this:
SELECT * FROM sqlite_master WHERE type = 'index' AND sql LIKE '%UNIQUE%'
you can programmatically build a select statement to see if any tuples point to more than one row. If you get back three columns, foo, bar and baz, create the following query
select count(*) from t
group by foo, bar, baz
having count(*) > 1
If that returns any rows, your index is not unique, since more than one row maps to the given tuple. If sqlite3 supports derived tables (I've yet to have the need, so I don't know off-hand), you can make this even more succinct:
select count(*) from (
select count(*) from t
group by foo, bar, baz
having count(*) > 1
)
This will return a single row result set, denoting the number of duplicate tuple sets. If positive, your index is not unique.
You are close:
1) If the index starts with "sqlite_autoindex", it is an auto-generated index for the primary key . However, this will be in the sqlite_master or sqlite_temp_master tables depending depending on whether the table being indexed is temporary.
2) You need to watch out for table names and columns that contain the substring unique, so you want to use:
SELECT * FROM sqlite_master WHERE type = 'index' AND sql LIKE 'CREATE UNIQUE INDEX%'
See the sqlite website documentation on Create Index
As of sqlite 3.16.0 you could also use pragma functions:
SELECT distinct il.name
FROM sqlite_master AS m,
pragma_index_list(m.name) AS il,
pragma_index_info(il.name) AS ii
WHERE m.type='table' AND il.[unique] = 1;
The above statement will list all names of unique indexes.
SELECT DISTINCT m.name as table_name, ii.name as column_name
FROM sqlite_master AS m,
pragma_index_list(m.name) AS il,
pragma_index_info(il.name) AS ii
WHERE m.type='table' AND il.[unique] = 1;
The above statement will return all tables and their columns if the column is part of a unique index.
From the docs:
The table-valued functions for PRAGMA feature was added in SQLite version 3.16.0 (2017-01-02). Prior versions of SQLite cannot use this feature.

Select Query in SQL + All the values in columns

I am having a table Table1 with columns id1, id2, id3 all the columns are nullable
I may enter null or value to all columns in rows.
My question is I need to select the rows whose all the column values should not be null.
Thanks
There are totally around 300 columns in the table. I can't do the is null property for all the columns in where condition.
The answer to use a "function" to test the null-values is correct. The syntax depends on the database. If ISNULL() does not exist in your database then try:
SELECT * FROM Table1 WHERE id1 IS NOT NULL AND id2 IS NOT NULL AND id3 IS NOT NULL
And there is no way to short this down even if you have 300 fields in your table.
Don't understand why this question is getting negitive reviews - This question can be extended to people who inherited a large table from a non-programmer in a community (I know from previous experience), and likewise if the table is unknown. To downgrade this because its '300' columns is pointless IMO.
You need to do this:
SELECT *
FROM yourtable
WHERE
column1 IS NOT NULL
AND column2 IS NOT NULL
AND column3 IS NOT NULL
AND ....
Best bet is to either rethink the design of your tables, splitting them if required.
otherwise best bet is do it progmatically - grab the table metadata, itterate through the columns and drynamically create the SQL from there. Most coding languages have access to the tables metadata, failing that a second SQL is required for it.
But, best bet is to think how can I design the table better.
Are you saying you want to select the rows where none of the columns are null?
SELECT id1, id2, id3
FROM Table1
WHERE id1 IS NOT NULL AND id2 IS NOT NULL AND id3 IS NOT NULL
Sorry - I might be being a bit thick here. You're trying to get back the rows that have got SOMETHING in one of the columns (other than the id column)?
Can't you do;
create vw_View_Fields1to5 as
select id from employees
where name is not null or description is not null or field3 is not null
or field4 is not null or field5 is not null;
create vw_View_Fields6to10 as
select id from employees
where field6 is not null or field7 is not null or field8 is not null
or field 9 is not null or field10 is not null;
(etc)
select id from vw_View_Fields1to5
union
select id from vw_View_Fields6to10 .... (etc)
You'd have to take a DISTINCT or something to cut down the rows that fall into more than one view, of course.
If you want the rows back that have NOTHING in any column other than id, you'd switch 'or blah is not null' to be 'and blah is null' (etc).
Does that make sense... or am I missing something? :-)
EDIT: Actually, I believe the UNION process will only bring back distinct rows anyway (as opposed to UNION ALL), but I could be wrong - I haven't actually tried this.... (yet!)
you can try CLR stored procedure (if you're using SQL Server) or move this logic to the other layer of your application using C# or whatever language you're using.
another option is to create the query dynamically, concatenating your WHERE clause and EXECute your dynamically generated query.
Are you just reading the data, or will you want to try and update the rows in question?
I'm just wondering if there's something you can go by making a half-dozen views, each one based on say 50 columns being NOT NULL, and then linking them with some kind of EXISTS or UNION statement?
Can you tell us a bit more about what you want to do with your result set?
For the first time whatever Georgi or engram or robsoft is the way. However for subsequent stuff you can if possible alter the table and add one more column, called CSELECTFLAG, and initially updated this to Y for all columns that have values and N for others. Everytime there is an insert this needs to be updated. This would help make your subsequent queries faster and easier.

Resources