SQLITE: Removing records by RowID - sql

I want to delete the last 1000 records in my sqlite DB.
The following statement executes with no errors, but deletes (affects) all records.
I use the following SQL statement:
DELETE FROM LOGS WHERE (SELECT ROWID FROM LOGS ORDER BY ROWID DESC LIMIT 1000)
Any ideas?

First check the sub-query return the last 1000 records
SELECT ROWID FROM LOGS ORDER BY ROWID DESC LIMIT 1000
If it returns the correct result, could you try the below query. I added ROWID IN in the WHERE clause
DELETE FROM LOGS WHERE ROWID IN (SELECT ROWID FROM LOGS ORDER BY ROWID DESC LIMIT 1000)

Related

Oracle sql query to GROUP BY, ORDER BY and delete the oldest records per ID

I want to write an oracle sql query to keep first three latest records ordered by TIMESTAMP and delete the rest for each MACHINE_ID.
I want to know how efficient i can do that. Hope you understand my question!!
Below is the table for example. All the records with USERFILE = 0 can be filtered out in the sql query.
**Result after - group by MACHINE_ID and sort by TIMESTAMP desc **
After leaving the first 3 latest records per MACHINE_ID and deleting the oldest records, final result should be
One method is:
delete from t
where t.timestamp not in (select t2.timestamp
from t t2
where t2.machine_id = t.machine_id
order by t2.timestamp desc
fetch first 3 rows only
);
For performance, you want an index on (machine_id, timestamp desc).
You can number the rows per machine and then delete all rows with a number greater than 3. Ideally we could simply delete from a query, but I'm getting ORA-01732: data manipulation operation not legal on this view when trying this in Oracle 19c.
We need two steps hence:
find the rows
delete the rows
The statement using rowid to acces the rows again quickly:
delete from mytable
where rowid in
(
select rowid
from
(
select
rowid,
row_number() over (partition by machine_id order by timestamp desc) as rn
from mytable
)
where rn > 3
);

What is rowID & rowNum (ROWID vs ROWNUM)

I'd like to know difference between rowID and rowNUM
And how to see both of these in our table.
when I execute this:
SELECT * FROM emp WHERE rownum=1
It returns one query but when I do the same for rowid it says
inconsistent datatypes: expected ROWID got NUMBER
And even in some of the tables, rownum returns null . Why so?
Please clarify this: rowid vs rownum?(Demo query)
Thank you
EDIT: Require to use alias to display ROWID and ROWNUM(as they're pseudocolumn)
like:
SELECT rownum r1, rowid r2 FROM emp
Both, ROWNUM and ROWID are pseudo columns.
Rowid
For each row in the database, the ROWID pseudo column returns the
address of the row.
An example query would be:
SELECT ROWID, last_name
FROM employees
WHERE department_id = 20;
More info on rowid here: https://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns008.htm
Rownum
For each row returned by a query, the ROWNUM pseudo column returns a
number indicating the order in which Oracle selects the row from a
table or set of joined rows. The first row selected has a ROWNUM of 1,
the second has 2, and so on.
You can limit the amount of results with rownum like this:
SELECT * FROM employees WHERE ROWNUM < 10;
More info on rownum here: https://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns009.htm
Difference
The actual difference between rowid and rownum is, that rowid is a permanent unique identifier for that row. However, the rownum is temporary. If you change your query, the rownum number will refer to another row, the rowid won't.
So the ROWNUM is a consecutive number which applicable for a specific SQL statement only. In contrary the ROWID, which is a unique ID for a row.
Rownum (numeric) = Generated Sequence Number of your output.
Rowid (hexadecimal) = Generated automatically at the time of insertion of row.
SELECT rowid,rownum fROM EMP
ROWID ROWNUM
----- ----------------------
AAAR4AAAFAAGzg7AAA, 1
AAAR4AAAFAAGzg7AAB, 2
AAAR4AAAFAAGzg7AAC, 3
AAAR4AAAFAAGzg7AAD, 4
AAAR4AAAFAAGzg7AAE, 5
Rowid gives the address of rows or records. Rownum gives a count of records
Rowid is permanently stored in the database. Rownum is not stored in the database permanently
Rowid is automatically assigned with every inserted into a table. Rownum is a dynamic value automatically retrieved along with select statement output.
It is only for display purpose.
row id shows the unique identification for row
rownum shows the unique default series of numbers.
select * from emp
where rownum<=5; (it will execute correctly and gives output first 5 rows in your table )
select * from emp
where rowid<=5; (wrong because rowid helpful to identify the unique value)

Fetch first 5 and last 5 records through a single statement

I am working on python sqlite3.
This statement gets records 5 - 14;
SELECT * FROM something LIMIT 5, 10;
But how do I get, lets say the first five and last five records through a single statement?
You can combine output of two select statement like this:
(SELECT * FROM `something` order by some_column_name
limit 0,5)
union
(SELECT * FROM `something` order by some_column_name desc
limit 0,5
)
Specify some ordering of rows, so that it will select rows accordingly.
Maybe the better way is using rowid in your order by clause to get the first and last rows based on inserting the rows:
select test from
(select test,rowid from table1 order by rowid asc limit 0,5)t1
union all
select test from
(select test,rowid from table1 order by rowid desc limit 0,5)t2;
Here is a sample in SQL Fiddle

How output distinct number of rows in SQL Server 2012

I have a query that results in more than 1 million of records in result table.
But I have to use Excel for further processing and it has a limit for such big data.
How can I query e.g. first 500.000 records and then the last?
I use SQL Server 2012.
Thanks in advance!
You could use the OFFSET FETCH clause like this:
/* Fetch the first 500k rows */
SELECT col1, col2, ...
FROM TheTable
ORDER BY Col1 OFFSET 0 ROWS FETCH NEXT 500000 ROWS ONLY;
/* Fetch the next 500k rows */
SELECT col1, col2, ...
FROM TheTable
ORDER BY Col1 OFFSET 500000 ROWS FETCH NEXT 500000 ROWS ONLY;
You will have to trim the values used for offset and fetch next to suit the number of rows you want to limit each query by and add extra fetch queries if you need to fetch more than the 1 million in my example.
You can use
select TOP 500000 * from table order by id -- to get the first half..
The bottom half requires knowing how they are ordered.. Assume ID is an ordering field
select * from
(select top 500000 * from table order by id DESC) xx
order by xx.id
SELECT TOP 500000 * FROM table_name
If you want to get the bottom-most values in the table, do an ORDER BY column_name ASC or DESC

Delete oldest records from database

I have a database with 1000 records.
I am trying to create an SQL statement so if the number of records grows above 1000, then the oldest records are deleted (i.e. the new records above 1000 'replace' the oldest records).
I am using SQLite, but I assume the usual SQL syntax will fit here.
If you use an auto-increment field, you can easily write this to delete the oldest 100 records:
DELETE FROM mytable WHERE id IN (SELECT id FROM mytable ORDER BY id ASC LIMIT 100)
Or, if no such field is present, use ROWID:
DELETE FROM mytable WHERE ROWID IN (SELECT ROWID FROM mytable ORDER BY ROWID ASC LIMIT 100)
Or, to leave only the latest 1000 records:
DELETE FROM mytable WHERE ROWID IN (SELECT ROWID FROM mytable ORDER BY ROWID DESC LIMIT -1 OFFSET 1000)
Assuming that your table has a Primary Key and a column with a timestamp indicating when the record was inserted), you can use a query along the lines of
delete from tableToDeleteFrom
where tablePK in
(select tablePK
from tableToDeleteFrom
where someThresholdDate <= #someThresholdDate)
For delete all records except the first record (min/max id) you can use:
SET #ls AS INT
SELECT #ls = MIN(id) FROM DATA
DELETE FROM DATA WHERE id <> #ls