SQLite how to delete rows in a table (C++)
-
Hello everybody. I have no database experience so I apologize in advance if my question is too trivial. I'm writing an application in C++ (Embarcadero C++ Builder Tokyo) and I'm using sqlite. I have a database with a table "EVENTI" with two columns ("DataOra" and "Evento") and about 6000 rows and I want to delete the first ~5000 rows to reduce the database size to about 1000 rows. I have to use a command like: "DELETE FROM EVENTI WHERE (condition)" but I don't know exactly how to write the condition. Is there a line identifier so I can write a condition like: "DELETE FROM EVENTI WHERE (LineId < 5000)" Or I have to read line 5000 (how?) and build a condition on the content of that line? Someone can help me? Thank you
-
Hello everybody. I have no database experience so I apologize in advance if my question is too trivial. I'm writing an application in C++ (Embarcadero C++ Builder Tokyo) and I'm using sqlite. I have a database with a table "EVENTI" with two columns ("DataOra" and "Evento") and about 6000 rows and I want to delete the first ~5000 rows to reduce the database size to about 1000 rows. I have to use a command like: "DELETE FROM EVENTI WHERE (condition)" but I don't know exactly how to write the condition. Is there a line identifier so I can write a condition like: "DELETE FROM EVENTI WHERE (LineId < 5000)" Or I have to read line 5000 (how?) and build a condition on the content of that line? Someone can help me? Thank you
You'll need to use a command like "DELETE FROM EVENTI WHERE (condition)", but we can't tell you what that condition is, since we don't know the table structure. You can't think of SQL tables like flat files. Successive SELECTS from a table won't necessarily return the rows in the same order. All tables should have a PRIMARY KEY, which uniquely identifies a given row. You should be able to use this to select the rows you wish to delete. Alternatively you may have a timestamp or other identifying piece of information in the row that will help you choose which rows to delete.
-
Hello everybody. I have no database experience so I apologize in advance if my question is too trivial. I'm writing an application in C++ (Embarcadero C++ Builder Tokyo) and I'm using sqlite. I have a database with a table "EVENTI" with two columns ("DataOra" and "Evento") and about 6000 rows and I want to delete the first ~5000 rows to reduce the database size to about 1000 rows. I have to use a command like: "DELETE FROM EVENTI WHERE (condition)" but I don't know exactly how to write the condition. Is there a line identifier so I can write a condition like: "DELETE FROM EVENTI WHERE (LineId < 5000)" Or I have to read line 5000 (how?) and build a condition on the content of that line? Someone can help me? Thank you
If "DataOra" or "Evento" are not your line numbering system then you have a problem. Assuming there is some sort of sequence in your data, date or number you could select the top 50000, get the sequence value and then delete anything less than the selected sequence. I would test this on a copy of the database :-D select - How to get Top 5 records in SqLite? - Stack Overflow[^] add an orderby your sequence field and you get the values for your where condition.
Never underestimate the power of human stupidity - RAH I'm old. I know stuff - JSOP
-
Hello everybody. I have no database experience so I apologize in advance if my question is too trivial. I'm writing an application in C++ (Embarcadero C++ Builder Tokyo) and I'm using sqlite. I have a database with a table "EVENTI" with two columns ("DataOra" and "Evento") and about 6000 rows and I want to delete the first ~5000 rows to reduce the database size to about 1000 rows. I have to use a command like: "DELETE FROM EVENTI WHERE (condition)" but I don't know exactly how to write the condition. Is there a line identifier so I can write a condition like: "DELETE FROM EVENTI WHERE (LineId < 5000)" Or I have to read line 5000 (how?) and build a condition on the content of that line? Someone can help me? Thank you
-
You'll need to use a command like "DELETE FROM EVENTI WHERE (condition)", but we can't tell you what that condition is, since we don't know the table structure. You can't think of SQL tables like flat files. Successive SELECTS from a table won't necessarily return the rows in the same order. All tables should have a PRIMARY KEY, which uniquely identifies a given row. You should be able to use this to select the rows you wish to delete. Alternatively you may have a timestamp or other identifying piece of information in the row that will help you choose which rows to delete.
Thank you k5054. I have not set a PRIMARY KEY in my table but the "DataOra" column contains a timestamp in the form "YYYY/MM/DD hh:mm:ss" so I think I could use this information to select the rows to delete. But to do this I need to read the value of row 5000 without any information about this row, I mean that I have not a PRIMARY KEY and I just know the row number, is this information enought to read row 5000? And if I read row 5000, then I can use a command like: "DELETE FROM EVENTI WHERE DataOra < 'YYYY/MM/DD hh:mm:ss'" or I have to convert in some way my timestamp? Thank you
-
If "DataOra" or "Evento" are not your line numbering system then you have a problem. Assuming there is some sort of sequence in your data, date or number you could select the top 50000, get the sequence value and then delete anything less than the selected sequence. I would test this on a copy of the database :-D select - How to get Top 5 records in SqLite? - Stack Overflow[^] add an orderby your sequence field and you get the values for your where condition.
Never underestimate the power of human stupidity - RAH I'm old. I know stuff - JSOP
Thank you Mycroft Holmes. My DataOra column contains a timestamp in the form "YYYY/MM/DD hh:mm:ss", as I answered k5054, so this seems a good reference. The data in my table is ordered, it is a sequence of events, so if I say "SELECT * FROM EVENTI ORDER BY DataOra ASC LIMIT 5000" I really select the first 5000 rows? How I put the result of SELECT in my WHERE condition? Thank you.
-
See SQLite Query Language: DELETE[^] for the LIMIT option, which may help you.
Thank you Richard for your helpfull suggestion.
-
Thank you Mycroft Holmes. My DataOra column contains a timestamp in the form "YYYY/MM/DD hh:mm:ss", as I answered k5054, so this seems a good reference. The data in my table is ordered, it is a sequence of events, so if I say "SELECT * FROM EVENTI ORDER BY DataOra ASC LIMIT 5000" I really select the first 5000 rows? How I put the result of SELECT in my WHERE condition? Thank you.
Now get the latest date from the result set and delete all record where the date is less than the latest date.
Never underestimate the power of human stupidity - RAH I'm old. I know stuff - JSOP
-
Thank you k5054. I have not set a PRIMARY KEY in my table but the "DataOra" column contains a timestamp in the form "YYYY/MM/DD hh:mm:ss" so I think I could use this information to select the rows to delete. But to do this I need to read the value of row 5000 without any information about this row, I mean that I have not a PRIMARY KEY and I just know the row number, is this information enought to read row 5000? And if I read row 5000, then I can use a command like: "DELETE FROM EVENTI WHERE DataOra < 'YYYY/MM/DD hh:mm:ss'" or I have to convert in some way my timestamp? Thank you
You should probably use a DATETIME field type for DataOra, but if you know that all your timestamps are 'YYYY/MM/DD hh:mm:ss', then then comparing as strings should work out OK. How you truncate your data is somewhat dependent on exactly what your need is. If you just want to delete approximately 5000 records, you could do SELECT count(*) FROM EVENT where DataOra < 'YYYY/MM/DD 00:00:00' and adjust the date and or time up/down until you get about 5000 and then use that date as your comparison. Or maybe you would be happy with just deleting records before Feb 01/2019 in which case you could just use '2019/02/01 00:00:00' as your comparison Alternatively, if you want to delete exactly 5000 records, ordering by timestamps, then this might work for you:
CREATE TEMP TABLE TMP(id INTEGER PRIMARY KEY AUTOINCREMENT, DataOra text);
INSERT INTO TMP(DataOra) SELECT DataOra from EVENT order by DataOra;
DELETE FROM EVENT where DataOra <= (SELECT DataOra from TMP where id = 5000);hope this helps. Don't forget to back up your data before you begin - just in case!
-
You should probably use a DATETIME field type for DataOra, but if you know that all your timestamps are 'YYYY/MM/DD hh:mm:ss', then then comparing as strings should work out OK. How you truncate your data is somewhat dependent on exactly what your need is. If you just want to delete approximately 5000 records, you could do SELECT count(*) FROM EVENT where DataOra < 'YYYY/MM/DD 00:00:00' and adjust the date and or time up/down until you get about 5000 and then use that date as your comparison. Or maybe you would be happy with just deleting records before Feb 01/2019 in which case you could just use '2019/02/01 00:00:00' as your comparison Alternatively, if you want to delete exactly 5000 records, ordering by timestamps, then this might work for you:
CREATE TEMP TABLE TMP(id INTEGER PRIMARY KEY AUTOINCREMENT, DataOra text);
INSERT INTO TMP(DataOra) SELECT DataOra from EVENT order by DataOra;
DELETE FROM EVENT where DataOra <= (SELECT DataOra from TMP where id = 5000);hope this helps. Don't forget to back up your data before you begin - just in case!
Sorry for the delay. Thank you for your detailed answer. Where is created the TMP table? In the same database where there is the EVENTI table? Thanks.
-
Sorry for the delay. Thank you for your detailed answer. Where is created the TMP table? In the same database where there is the EVENTI table? Thanks.
In my example the TMP table is created with the attribute TEMP, which means that the table will be TEMPORARY, and are dropped when the connection that created them closes. TEMP tables are created in the "temp" database (as per sqlite docs). Other than only existing for the current session, TEMP tables are just like regular tables - they can be indexed, altered, updated, etc.
-
In my example the TMP table is created with the attribute TEMP, which means that the table will be TEMPORARY, and are dropped when the connection that created them closes. TEMP tables are created in the "temp" database (as per sqlite docs). Other than only existing for the current session, TEMP tables are just like regular tables - they can be indexed, altered, updated, etc.
Thank you very much k5054 for your explanation! :thumbsup: