How to fetch ROWID / ROWNUM in mimer-sql? I need too update table based on ROWID, so need to fetch rowid and update the specfic rowid only.
Related
I need to understand how to add a statement that will delete the results of the following query:
I understand that a DELETE statement with a WHERE clause would normally be used, but because I'm SELECTING two different columns, the where clause doesn't accept the comma. I've not yet been able to figure out how to turn this into a CTE (but maybe that's overkill?) and then call it in a DELETE statement later (assuming that's even an option). Examples always have the DELETE FROM..., or WHICH statements, neither of which seem implementable under this code. Do I have to rewrite my code so it includes a WHICH statement?
SELECT field1, field2
FROM table
GROUP BY field1, field2
HAVING SUM(field3) IS NULL
Expecting to be able to institute a DELETE statement to delete the results of the query.
I believe that you could use (assuming that the table is not a WITHOUT ROWID table) :-
DELETE FROM mytable WHERE rowid IN (SELECT rowid FROM mytable GROUP BY field1, field2 HAVING SUM(field3) IS NULL);
An alternative using a CTE (where the CTE has been given the name deletions) would be :-
WITH deletions(rowid) AS (SELECT rowid
FROM mytable
GROUP BY field1, field2
HAVING SUM(field3) IS NULL
)
DELETE FROM mytable WHERE rowid IN (SELECT rowid FROM deletions);
note that mytable has been used as the table name instead of table.
Considering the comment
Primary key is field1
then :-
DELETE FROM mytable WHERE field1 IN (SELECT field1 FROM mytable GROUP BY field1, field2 HAVING SUM(field3) IS NULL);
could be used, this would then work whether or not the table is defined as a WITHOUT ROWID table, a similar change could be applied to the CTE version.
Notes
Using GROUP BY on a PRIMARY KEY, as it is UNIQUE, will result in as many groups and therefore rows, as there are rows. Effectively the query could be SELECT field1 FROM mytable WHERE field3 IS NULL and therefore the deletion could simply be DELETE FROM mytable WHERE field3 IS NULL.
If this were not the case and field1 was not the PRIMARY KEY, then the complication is that values per group that are not aggregated values are values from an arbitrarily selected row. In short you would delete 1 from a number of the rows that where grouped.
I want to have riggers that set the last_modified column automatically each time a row in updated or inserted.
Lets say I have an ID that is unique to each row.
This is my query:
CREATE TRIGGER insert_trigger
AFTER INSERT ON TABLE_NAME
BEGIN
update TABLE_NAME set last_modified =strftime('%Y-%m-%d %H:%M:%S:%s','now', 'localtime') where id = old.id;
END;
After creating this trigger, when I try to insert I get the error:
no such column: old.id
I can understand why I get this error, but how can I create a proper trigger?
When inserting, there is no old row.
To get the ID of the new row, use NEW.id.
I have two tables namely table1 and table2.
When table1 is updated, I want to insert the row being updated to table2 so that table2 serves as a log.
table1 has column1,column2,column3,column4....column10
table2 has column1,column2,column3,column4
So while inserting into table2, I just want column1,column2,column3,column4 from table1.
This will be simple if you just want to add the record updated from table1 to table2 and you can use after update
delimiter //
create trigger update_table1 after update on table1
for each row
begin
insert into table2
(column1,column2,column3,column4)
values
(old.column1,old.column2,old.column3,old.column4);
end; //
delimiter;
I want to create a table with a field that is unique and limited to a certain value. Lets say that the limit is 100, the table is full, I remove a random row, and when I create a new row it has the value that was freed before.
It doesn't need to be the fastest thing in the world (the limit is quite small), I just want to implement it in a DB.
Any ideas?
Create one more column in main table, say deleted (integer, 0 or 1). When you need to delete with certain id, do not really delete it, but simply update deleted to 1:
UPDATE mytable SET deleted=1 WHERE id = <id_to_delete>
When you need to insert, find id to be reused:
SELECT id FROM mytable WHERE deleted LIMIT 1
If this query returns empty result, then use INSERT to create new id. Otherwise, simply update your row:
UPDATE mytable SET deleted=0, name='blah', ... WHERE id=<id_to_reuse>
All queries reading from your main table should have WHERE constraint with NOT deleted condition:
SELECT * FROM mytable WHERE NOT deleted
If you add index on deleted, this method should work fast even for large number of rows.
This solution does everything in a trigger, so you can just use a normal INSERT.
For the table itself, we use an autoincrementing ID column:
CREATE TABLE MyTable(ID INTEGER PRIMARY KEY, Name);
We need another table to store an ID temporarily:
CREATE TABLE moriturus(ID INTEGER PRIMARY KEY);
And the trigger:
CREATE TRIGGER MyTable_DeleteAndReorder
AFTER INSERT ON MyTable
FOR EACH ROW
WHEN (SELECT COUNT(*) FROM MyTable) > 100
BEGIN
-- first, select a random record to be deleted, and save its ID
DELETE FROM moriturus;
INSERT INTO moriturus
SELECT ID FROM MyTable
WHERE ID <> NEW.ID
ORDER BY random()
LIMIT 1;
-- then actually delete it
DELETE FROM MyTable
WHERE ID = (SELECT ID
FROM moriturus);
-- then change the just inserted record to have that ID
UPDATE MyTable
SET ID = (SELECT ID
FROM moriturus)
WHERE ID = NEW.ID;
END;
How can I remove a row from a table that has lowest rowid?
Thank you.
DELETE FROM
MyTable
WHERE
Id = (SELECT MIN(Id) FROM MyTable);
In most cases like this, rowid is an indexed column. If that is the case the much faster solution is:
DELETE FROM
tablename
WHERE
rowid= (SELECT rowid FROM tablename order by rowid limit 1)
If rowid is NOT indexed then:
DELETE FROM
tablename
WHERE
rowid= (SELECT MIN(rowid) FROM tablename)
I'd still test the first one as it will often be faster, even if rowid is not indexed.
DELETE FROM
tablename
WHERE
rowid= (SELECT MIN(rowid) FROM tablename)