Getting the nth highest value row in sqlite - sqlite

My problem sounds simple enough but I havent been able to find a solution that works.
I need to get the row with say 5th highest value of an attribute with sqlite.. Entries are random of course. So its not sorted.
I did find a few solutions with sql but apparently not all sql functionalities are supported by sqlite.
Thanks in advance

To remove duplicates, use DISTINCT.
To get only the fifth value, use the OFFSET clause:
SELECT DISTINCT SomeAttribute
FROM MyTable
ORDER BY 1 DESC
LIMIT 1 OFFSET 4

Try the 'Limit' keyword.
The query below will eliminate the first four rows by using 'not in'.
Then the last 'Limit 1' will select the 5th row.
Select * from Programs
Where ProgramId not in
(Select ProgramId From Programs order by programId limit 4 )
order by programId Limit 1
EDIT:
To add in CV's 'Distinct' and 'OFFSET' suggestions, the finished query would look something like...
Select StudentName From Students Where Marks in (
Select distinct Marks from Students Order By Marks desc Limit 1 offset 4)

Related

I want to count ocurrences of a Text in a Field in MariaDB

In MariaDB, I want to insert count ocurrences of a Text in a Field in another table.
something like:
Insert Into UniqueFacts (Text, Frecuency)
(SELECT DISTINCT(Fact) , count(*) FROM AllFacts group by Fact)
But this sentence no insert frecuencies.
Thank you.
DISTINCT is not a function. What you have is the same as
SELECT DISTINCT
Fact, COUNT(*)
FROM ...
DISTINCT and GROUP BY are always(?) redundant with each other.
To fix your query, simply remove one word: DISTINCT; keep the GROUP BY.

SQLite, Sorting a data base by a timestamp

this is my first time asking a question, so bear with me and thanks in advance for any response I get.
I am using sqlite3 on a Macbook pro.
Every record in my database has a time stamp in the form YYYY-MM-DD HH:MM:SS, and I need to sort the entire database by the time stamps. The closest answer I have found to letting me do this is SELECT * FROM Table ORDER BY date(dateColumn) DESC Limit 1 from SQLite Order By Date but this returns the most recent date. I would love to be able to apply this but I am just learning sqlite can't figure how to do so.
Change the limit to the number of rows you want:
SELECT * FROM Table ORDER BY dateColumn DESC Limit 10000000;
you can figure out how many rows you have using
SELECT count(*) FROM Table;
and give a limit greater than that number. Beware: If you want all rows you should really put a limit, because if you don't put a limit and simply do
SELECT * FROM Table ORDER BY dateColumn DESC;
it will limit the output to a certain number depending on your system configurations so you might not get all rows.
When you don't want a limit, omit it.
Please note that it is not necessary to call the date function:
SELECT * FROM MyTable ORDER BY dateColumn;
Just leave off the "Limit 1". The query means "SELECT *" (the star means return all the columns) "FROM Table" (kind of obvious, but from the table name you enter here) "ORDER BY date(dateColumn)" (again, somewhat obvious, but this is the sort order where you put your data column name) "DESC" (backwards sort, leave this off if you want ascending, aka forward, sort) and "Limit 1" (only return the first record in the record set).

rownum equivlent in teradata

How to convert rownum in following query(oracle) to teradata equivalent:
and not exists(select 1
from CSE, SPD
WHERE cse.id=spd.id
AND ROWNUM = 1
AND CSE.STATUSID IN(6,7,8,13)
thanks.
There's no ROWNUM in Teradata, but you can usually rewrite it using ROW_NUMBER plus QUALIFY.
In your case there's no need for ROWNUM at all (at least logically, maybe Oracle prefers it to do a better plan), this is exactly the same:
and not exists(select *
from CSE, SPD
WHERE cse.id=spd.id
AND CSE.STATUSID IN(6,7,8,13)
Teradata specifically does not have any rownumber attached to the rows in a table as in Oracle.
But it has two analytical functions such as ROW_NUMBER() and RANK() which will give a number to your row and then you can accordingly pick you data.
You may use something like below:
QUALIFY ROW_NUMBER()(Partition by Id order by date)=1
Here, Partition by with a column or few columns can be used to group your data, like suppose some id column in your table and order by will sort the data for that id in your table according to the order by column you provide and =1 means it then chooses the row for that id which is given row number as 1.
Use somethin like below:
row_number() over(partition by '' order by statusid asc) as rownum_1
qualify rownum_1 = 1
The above statement imitates the rownum functionality of oracle.
you can use row_number. keep in mind the columns you want to take into consideration while calculating the row number. You can use qualify for the same.
other options are dense_rank, rank etc. In your case you can use rank in the sub query and put the condition rank = 1. if you want the syntax do let me know.
As you using this tweak for efficiency, I suppose, QUALIFY ROW_NUMBER() and other window functions will not suite you during their heavy use of CPU.
You can simply remove this part, Teradata should be fine.

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.

SQLite - getting number of rows in a database

I want to get a number of rows in my table using max(id). When it returns NULL - if there are no rows in the table - I want to return 0. And when there are rows I want to return max(id) + 1.
My rows are being numbered from 0 and autoincreased.
Here is my statement:
SELECT CASE WHEN MAX(id) != NULL THEN (MAX(id) + 1) ELSE 0 END FROM words
But it is always returning me 0. What have I done wrong?
You can query the actual number of rows withSELECT Count(*) FROM tblName
see https://www.w3schools.com/sql/sql_count_avg_sum.asp
If you want to use the MAX(id) instead of the count, after reading the comments from Pax then the following SQL will give you what you want
SELECT COALESCE(MAX(id)+1, 0) FROM words
In SQL, NULL = NULL is false, you usually have to use IS NULL:
SELECT CASE WHEN MAX(id) IS NULL THEN 0 ELSE (MAX(id) + 1) END FROM words
But, if you want the number of rows, you should just use count(id) since your solution will give 10 if your rows are (0,1,3,5,9) where it should give 5.
If you can guarantee you will always ids from 0 to N, max(id)+1 may be faster depending on the index implementation (it may be faster to traverse the right side of a balanced tree rather than traversing the whole tree, counting.
But that's very implementation-specific and I would advise against relying on it, not least because it locks your performance to a specific DBMS.
Not sure if I understand your question, but max(id) won't give you the number of lines at all. For example if you have only one line with id = 13 (let's say you deleted the previous lines), you'll have max(id) = 13 but the number of rows is 1. The correct (and fastest) solution is to use count(). BTW if you wonder why there's a star, it's because you can count lines based on a criteria.
I got same problem if i understand your question correctly, I want to know the last inserted id after every insert performance in SQLite operation. i tried the following statement:
select * from table_name order by id desc limit 1
The id is the first column and primary key of the table_name, the mentioned statement show me the record with the largest id.
But the premise is u never deleted any row so the numbers of id equal to the numbers of rows.
Extension of VolkerK's answer, to make code a little more readable, you can use AS to reference the count, example below:
SELECT COUNT(*) AS c from profile
This makes for much easier reading in some frameworks, for example, i'm using Exponent's (React Native) Sqlite integration, and without the AS statement, the code is pretty ugly.

Resources