How to get last inserted all records in mysql - mysql

Actually I don't know how to get last inserted records in two table.
I want to get last recently inserted all records in table.
I used LAST_INSERT_ID() function but it gives only one last record and i want multiple records in table.

Seems you want to get all records using LAST_INSERT_ID(), which can give only last inserted record, you can't get second last inserted record with adding any extra where clause or something like that. Either you could fetch all record directly or you can get last insert id first then fetch all (other) record based on your requirement.

I'm looking into this myself right now and the only way I can come up with is to retrieve the number of affected rows from the most recent query, and then select that many rows from the table, with the selection ordered by ID (or whatever is most appropriate to your use case) in Descending order, thus:
The insertion query:
INSERT INTO db.table (id,var1,var2)
VALUES
(NULL,'value1','value2')
(NULL,'value3','value4')
(NULL,'value5','value6')
Use mysql_affected_rows() to retrieve how many rows were inserted.
(In PHP this would be $number = $mysqli_object->affected_rows - your code implementation may differ)
then fetch the rows using that value as the LIMIT value:
SELECT * FROM db.table ORDER BY id DESC LIMIT $number
Ideally you'd wrap that up in a method or function dependant on your coding and use case.

Related

How to ensure SELECTing new records doesn't miss any records?

I have a table mytable that is continuously being updated with new records.
I'm trying to get the most recent records using the method below ([lastId] is largest id of the previous select):
SELECT *
FROM mytable
WHERE id > [lastId]
ORDER BY id DESC
But I believe ids (and timestamps if I use it) are not necessarily inserted in order so there is a (small) possibility of missing some records. How can I get around this?
--EDIT--
The id field is AUTOINCREMENT.
Can you add a timestamp to the table and let the process that inserts records insert with current time?

mysql / java executeUpdate how to return matched rows and updated rows

I need to perform an update on a given table with a condition C, with a java driver.
If there is no row matching the condition C, i need to insert a new entity in the table.
If the row exists, then the update is enought.
To do so, is it possible to return from an update query the two following informations :
-Matched rows count
-Updated rows count
I believe the executeUpdate only return the number of rows updated.
The problem is that it might be zero if the update query doesn't update anything, so i have no way to know if 0 means no match (and i'll need to perform an insert) or no update.
Note : A workaround could be to insert a random field (or date), that would be updated everytime, but i'd prefer a better solution.
Thanks
The number of updated and matched rows are the same. Even if the row already has the values passed in the update, it will be counted as an updated row:
id name
1 foo
update mytable set name = 'foo' where id = 1;
--> 1 row updated

MySQL, ORDER BY insertion order, no sorting columns

How can I order values from a table, ascending from the time they were inserted. There is no special column for this matter, like a timestamp or autoincrement.
I know this is not recommended to do... Still I would like to know how to do this.
As I understand from the answers, if no sorting columns e.g: timestamp or autoincremental were added before the values were inserted, there is no way of sorting them by insertion.
There is no guarantee that rows will be returned in any particular order without an ORDER BY clause in the query.
Consider a simple query that returns all columns of all rows in a table. For example:
SELECT * FROM mytable ;
For that query, it is likely that MySQL will perform a full table scan, from the beginning of the table. So it is likely that the rows will be returned in the order they are found in physical storage.
This may roughly correspond to the order that rows were inserted, if there have been no deletes, no updates and no reorganization, where space for an inserted row was later reclaimed, and reused to store a newly inserted row.
But this behavior is NOT guaranteed.
To return the rows in the order that they were inserted, the query must specify the sequence that rows are to be returned, by including an ORDER BY clause.
For the rows to be returned in "insertion order", that means the query needs to be able to have that information available, or be able to derive that. For a simple query against a single table, that means the information needs to be stored in the row.
You can ORDER BY something you can get out of your table. If you do not have anything in there that can be used to find out the order you need, you cannot order by it.
Depending on the data in the table, you may be able to order by the id of the data - if the data has a single incremental integer to assure PK uniqueness. There is no other way to sort on insertion order unless the data is captured and recorded in the table.
I don't know of anything in MySQL that retains extra (meta) information on records that you have not specified at the table level.
There needs to be a column to order your query by. Usually this would be an insertion timestamp, or incrementing id/incrementing key. There is no way to guarantee the order otherwise, because there is no record of it.
relevant thread from MySQL forum

MySQL: retrieving the newest inserted data

After inserting new data into a table, I need to select some of the new data straight after, so I can use it for inserting into another table.
The only way I can think of doing this is using the 'datetime' field I have in my row, but how would I retrieve the latest date/time inserted.
INSERT statement with NOW() value for datetime
society_select = SELECT socID, creator, datetime FROM societies.society WHERE datetime='[..datetime is the newest...]';
Hope that makes sense. Thank you
There are a number of ways to do this.
Why not make use of a trigger for this?
When a trigger creates a record you can get the id's of the records inserted. You can then do a select and insert new values into the relevant table.
MYSQL has loads of resources on using triggers.
http://dev.mysql.com/doc/refman/5.0/en/triggers.html
Or you can get the number of rows affected then use this to get the required result set in a select statement.
Get the last inserted ID?
If you are inserting one row into the database at a time then you would be able to get the last inserted id from MYSQL. This will be the Primary Key value of the record you last inserted into the database.
You would basically do something like this in mysql:
SET #inserted_id = LAST_INSERT_ID();
Or in PHP you can use the function:
mysql_insert_id(&mysql);
http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html
Sort the results by their datetime in descending order, and select the first of them.
society_select = SELECT socID, creator, datetime FROM societies.society ORDER BY datetime DESC LIMIT 1;
you can use this with an auto increment filed. after inserting data you can retrieve the list inserted id from the table. and use that id to get the latest record.
A trigger as suggested is an option. If you don't want to use that for some kind of reason you can:
Add an integer primary key with auto_increment as ID and sort it DESC (e.g. INT(11))
Sort descending on a timestamp column (ofcourse with an index on it)
Use a trigger after inserting the data. This is for sure the cleaner way.
Another option is to use a method like mysql_insert_id. Assumed that you use PHP. There are of course equivalent methods in other languages as well.
Sorting is not an option(if not wrapped smart in transaction) - If you have multiple writes and reads on the table this might end up pretty ugly.

Deleting Duplicates in Access 2003

I have an Access 2003 table with ~4000 records which was made from 17 different tables. Roughly half of these records are duplicates. There is no unique identifying column (id, name etc). There is an id column which was auto filled when the tables were combined meaning that the duplicates aren't completely identical (though this column could be removed if it makes things easier).
I have used the Access Find Duplicates Query Wizard which gives me a list of the duplicated records but won't let me delete them (seriously what use is this query if I can't delete them?). I've tried converting the generated query to a remove query but that changes the number of rows that it finds. I'd alter the sql by hand but it's a bit beyond me and is 7 lines long.
Does anyone know a good way of getting rid of the duplicates?
The reason the find duplicates query won't let you delete the records is because it is basically just an aggregate query, it is counting the number of duplicates it finds and returning the cases where the count is greater than 1.
Consider that if you did make a delete query based on the find duplicates, it would delete all rows that have duplicate values, which is maybe not what you want. You want to delete all but one of the duplicates.
You should try to delete all duplicates of a record apart from one, excluding the ID column in your comparison. I suggest the simplest way to do this is to make a make-table query of all the unique values (Select Distinct Field1, Field2... from MyTable) instead for every field except for the ID field, using the results in a to create a new table of around 2000 records (if half are duplicates).
Then, create an ID column on your new table, use an update query to update this ID to the first matching ID in the original table (you could do this using DLookup, which will return the first EXPRESSION value where CRITERIA is true in DOMAIN).
The DLookup() function returns one
value from a single field even if more
than one record satisfies the
criteria. If no record satisfies the
criteria, or if the domain contains no
records, DLookup() returns a Null.
Since you are identifying the first matching ID based on all the other fields, which are unique values, the unmatched IDs will belong to duplicates. You will be reversing the PK relation, identifying the first matching key given a set of unique fields. After that, you should set the ID to be PK. Of course this assumes the ID has no inherent meaning, and you don't care about keeping one particular ID for a given duplicated row over any of the IDs belonging to the other duplicated rows. This assumes you care about the data in the ID column so you want to preserve it for all remaining rows, otherwise just ignore the DLookup step and do a Select Distinct on all columns apart from the ID.
Use a select with all columns except the ID column:
SELECT DISTINCTROW Column1, Column2, Column3
INTO MYNEWTABLE
FROM TABLE
You can simply swap the names.
This solution will give you a new table with non duplicates.
The following will preserve original IDs and do it in one step:
DELETE FROM table_with_duplicates
WHERE table_with_duplicates.id NOT IN
(SELECT max(id)
FROM table_with_duplicates
GROUP BY duplicated_field_1, duplicated_field_2, ...
)
Now you have the original table with no duplicates and preserved ids.
And always remember to backup you data before trying large DELETEs.
DELETE * FROM table_with_duplicates
WHERE table_with_duplicates.ID In
(SELECT max(ID)
FROM table_with_duplicates
GROUP BY [duplicated_field_1]
HAVING Count(*)>1
)
Actually I Found A very simple solution took a while but it all of your fields across are the same like a complete duplicate record then just make one query with every field and sort by "Group BY". Thus the duplicates will combine and you can just append this information to a new table and rename it the same as the existing table. If you have a primary key field you could just ignore it in the query and then it would still combine the data (assuming that you don't care about the data in the primary field). I don't know why no one has mentioned this solution took me 5 hr. to come up with. :)