Unable to select highest value from a column - php

I have suffered with this for to long. It is turning me nuts...
I just want to take the max value of a column, add 1 to id and then insert a new entry.
The table has a column 'id' and lets say 'name' and 'age'
The problem is that the $new_id variable is not selecting the highest value from the id column. I know I am doing something wrong... but what??
Please help, I know this must be a pretty basic issue, but I have been looking at this for hours...
$relations_table="xxx_sobipro_relations";
$sql="SELECT * FROM '$relations_table' ORDER BY id DESC LIMIT 1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
$new_id = $row[id] + 1;
//more code
$query="INSERT INTO $relations_table (id, pid, oType, position, validSince)
VALUES ($new_id, 2, 'testtest' , $position , NOW() )";

Use this instead:
SELECT COALESCE(MAX(id)+1,0) FROM `$object_table`

SELECT * FROM `$object_table`
table names and field names not in '' but `` (backticks)
And you should ask the database for errors...
and you should NOT use the mysql extension anymore, but switch to mysqli or PDO...

You should look into AUTO_INCREMENT - turning that on for your id column will cause it to increase by one automatically every time you insert a row. That way, you won't have to specify id when you do the insertion, because MySQL keeps track of it for you.

You can do this on your insert:
$query="INSERT INTO $relations_table (id, pid, oType, position, validSince)
VALUES ((SELECT MAX(id)+1 FROM $object_table), 2, 'testtest' , $position , NOW() )";
Auto_increment is a better option, but this will work when you can't auto_increment.

First, it's $row['id'] not $row[id].
Second, mysql_* is deprecated, do not use it. Instead use PDO or mysqli.
Third, you can use MAX to get maximum value from column. SELECT MAX(id) FROM '$object_table' LIMIT 1.
And most important, set id field to autoincrement and don't set it (MySQL will do it).

So, the query you're looking for is:
SELECT MAX(id) FROM table
But many databases provide an "auto-increment" functionality where you can specify a column (in this case id) to be the primary key and have its value auto-increment, so you don't have to do any of this.

Related

Insert distinct records in the table while updating the remaining columns

This is actually a form to update the team members who work for a specific client, When i deselect a member then it's status turns to 0.
I have a table with all unique records. table consists of four columns -
first column is `id` which is unique and auto_incremented.
second column is `client_id`.
third column is `member_id`. (these second and third columns together make the primary key.)
fourth column is `current` which shows the status (default is 1.).
Now i have a form which sends the values of client_id and member_id. But this forms also contains the values that are already in the table BUT NOT ALL.
I need a query which
(i) `INSERT` the values that are not already in the table,
(ii) `UPDATE` the `current` column to value `0` which are in the table but not in the form values.
here is a screenshot of my form.
If (select count(*) from yourtable where client_id = and member_id = ) > 0 THEN
update yourtable set current = 0;
ELSE
insert into yourtable (client_id,member_id,current) values (value1,value2,value3)
First of all check if the value exists in the table or not, by using a SELECT query.
Then check if the result haven't save value so it will be inserted, else show an error .
This would be a great time to create a database stored procedure that flows something like...
select user
if exists update row
else insert new row
stored procedures don't improve transaction times, but they are a great addition to any piece of software.
If this doesn't solve your problem then a database trigger might help out.
Doing a little research on this matter might open up some great ideas!
Add below logic in your SP
If (select count(*) from yourtable where client_id = <value> and member_id = <value>) > 0 THEN
update yourtable set current = 0;
ELSE
insert into yourtable (client_id,member_id,current) values (value1,value2,value3)
if you want simple solution then follow this:
*) use select with each entry in selected team.
if select returns a row
then use update sql
else
use insert sql.
In your case member_id & client_id together makes the primary key.
So , you can use sql ON DUPLICATE KEY UPDATE Syntax.
Example:
$sql="INSERT INTO table_name SET
client_id='".$clientId."',
member_id='".$member_id."',
current='".$current."'
ON DUPLICATE KEY
UPDATE
current = '".$current."'
";
In this case when member_id & client_id combination repeats , it will automatically executes update query for that particular row.

How to get last inserted id from table MySQL [duplicate]

This question already has answers here:
How do I get the last inserted ID of a MySQL table in PHP?
(16 answers)
Last inserted id from specific table
(8 answers)
Closed 5 years ago.
I am running 1 script in php for that I need last inserted id in subscription table. By using that id I want to make notification note for that subscription.
I used:
SELECT LAST_INSERT_ID() FROM subscription
I am getting 0 instead of real last inserted value.
If you use php to connect to mysql you can use mysql_insert_id() to point to last inserted id.
Like this :
mysql_query("INSERT INTO mytable (1, 2, 3, 'blah')");
$last_id = mysql_insert_id();
See this : mysql_insert_id()
LAST_INSERT_ID() returns the last id from a previous insert statement. If you want the most recently inserted record and are using Auto Increment Prime keys, you can use the code below:
SELECT MAX( id ) FROM subscription;
If you need to know what the NEXT id will be, you can get this from INFORMATION_SCHEMA
SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'test'
mysql_insert_id
This question has already been answered many times: MySQL: LAST_INSERT_ID() returns 0
You are using that function out of context. It will only work if you inserted a row immediately prior thusly:
INSERT INTO 'subscription' (name) VALUES ('John Smith');
SELECT LAST_INSERT_ID() FROM subscription
You can however select the row with the highest id, which logically would be the most recently added...
SELECT MAX( id ) FROM subscription;
The standard approach however is to simply call mysqli_insert_id or mysql_insert_id (depending on whether you are using the mysqli or mysql PHP library. I should add that the mysql library is very inadvisable to use since it is almost completely deprecated). Here's what the whole thing would ideally look like:
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
$mysqli->query("INSERT INTO 'subscription' (name) VALUES ('John Smith');");
printf ("New Record has id %d.\n", $mysqli->insert_id);
//Output is something like: New Record has id 999
If however you didn't insert a subscription in the same script as collecting the most recent row ID, use the 'select max' approach. This seems unlikely given that you mentioned '1 script'
Also, if your ID's are non-consecutive, or you do not have an ID field, or you have row ID's higher than the one you just added you should probably consider a 'date_added' column to determine which one was really the latest. These scenarios are rather unlikely however.
this is the better approach 2 and 3 works but MAX(id) take more time to execute.
SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'dbName' AND TABLE_NAME = 'tableName';
SELECT tableName.id FROM tableName ORDER BY tableName.id DESC LIMIT 0,1;
SELECT MAX( id ) FROM tableName;
This will always give you the maximum id, which says the biggest number is the last inserted one
SELECT MAX(id) as MaximumID FROM subscription;
$last_id=mysql_query("SELECT id FROM `table_name` ORDER BY id DESC LIMIT 0 , 1" );
$row=mysql_fetch_assoc($last_id);
echo $row['id'];
Replace id by your id field name in database and table_name by your table name.

accessing ID of mysql insert during the insert

Is there any way to access the id of the auto increment for use inside the query.
for instance Wordpress puts the id of the insert in the GUID of the same row, is there any way i can access the id that the row will take during the insertion.
Or maybe there is some quick way for me to find out what the current AI counter is at, so I know what the one going in will be?
I need this because I am trying to backfill the WP posts table into a new custom post type I am using, and I need to have the id of the insert to put inside the GUID column.
Maybe the mysql LAST_INSERT_ID() function can help you.
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
I assume that you want some sort of column with the same value as the user ID.
But why should you do that? just use the user ID, even if you use it for example as the refer ID.
AFAIK, you can't access the auto_increment value of a row being inserted. I suggest to insert the row, then read its ID and update it to fill the fields that you need to know the ID for.
(Why do you need that? It seems your database needs some normalization, if you have such an egg-chicken problem.)
This is one way of doing it. This worked for me:
1) just execute 2 separate MySql queries. The first one inserts the post values into the wp_posts table. You should insert into all columns except in the column "guid" insert some placeholder, like "0".
2) the second query is executed right after the first one and here you can call the LAST_INSERT_ID() function to get the true last insert ID of the previous query. This second query updates the "guid" field with the right ID number.
You can insert this into the loop for mass-inserting of WP posts from csv file for example.
You should do this when the site is off-line or lock the tables first so no other query request comes in between form somewhere else.
Example: 1st query (sorry for the column formatting but it is easier to debug):
mysql_query("INSERT INTO wp_posts(
ID,
post_author,
post_date,
post_date_gmt,
post_content,
post_title,
post_excerpt,
post_status,
comment_status,
ping_status,
post_password,
post_name,
to_ping,
pinged,
post_modified,
post_modified_gmt,
post_content_filtered,
post_parent,
guid,
menu_order,
post_type,
post_mime_type,
comment_count
) VALUES (
'null',
'1',
'$timestmp',
'$timestmp',
'$content',
'$posttitle',
'',
'publish',
'open',
'open',
'',
'$postname',
'',
'',
'$timestmp',
'$timestmp',
'',
'0',
'$uiai',
'0',
'post',
'',
'0'
)") or die(mysql_error());
2nd query:
$uid = mysql_insert_id();
$uiai = 'http://yoursite.net/wordpress/?post_type=post&p='.$uid;
mysql_query("UPDATE wp_posts SET guid = '$uiai' WHERE ID = '$uid'");
...also, when you are looping through many inserts, sometimes it can max out the maximum allowed execution time for PHP script and the upload gets interrupted. It helps to use set_time_limit(0); throughout the script so the max allowed time counter is regularly reset.
...hope this helps :)
Perhaps you could use AUTO_INCREMENT value of your table in information_schema.tables in an INSERT ... SELECT query. In theory INSERT ... SELECT should lock information_schema.tables and AUTO_INCREMENT value should be the Id which is used for next INSERT. But you should hardly test this and consider performance issues.
use mysql_insert_id() to get last inserted id
You can see more information at:
http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html
I ended up just pulling out the last id like so:
$this->lID = mysql_fetch_assoc(mysql_query("SELECT ID FROM wp_posts ORDER BY ID DESC LIMIT 1"));
$this->lID = $this->lID[ID];

How to get ID of the last updated row in MySQL?

How do I get the ID of the last updated row in MySQL using PHP?
I've found an answer to this problem :)
SET #update_id := 0;
UPDATE some_table SET column_name = 'value', id = (SELECT #update_id := id)
WHERE some_other_column = 'blah' LIMIT 1;
SELECT #update_id;
EDIT by aefxx
This technique can be further expanded to retrieve the ID of every row affected by an update statement:
SET #uids := null;
UPDATE footable
SET foo = 'bar'
WHERE fooid > 5
AND ( SELECT #uids := CONCAT_WS(',', fooid, #uids) );
SELECT #uids;
This will return a string with all the IDs concatenated by a comma.
Hm, I am surprised that among the answers I do not see the easiest solution.
Suppose, item_id is an integer identity column in items table and you update rows with the following statement:
UPDATE items
SET qwe = 'qwe'
WHERE asd = 'asd';
Then, to know the latest affected row right after the statement, you should slightly update the statement into the following:
UPDATE items
SET qwe = 'qwe',
item_id=LAST_INSERT_ID(item_id)
WHERE asd = 'asd';
SELECT LAST_INSERT_ID();
If you need to update only really changed row, you would need to add a conditional update of the item_id through the LAST_INSERT_ID checking if the data is going to change in the row.
This is officially simple but remarkably counter-intuitive. If you're doing:
update users set status = 'processing' where status = 'pending'
limit 1
Change it to this:
update users set status = 'processing' where status = 'pending'
and last_insert_id(user_id)
limit 1
The addition of last_insert_id(user_id) in the where clause is telling MySQL to set its internal variable to the ID of the found row. When you pass a value to last_insert_id(expr) like this, it ends up returning that value, which in the case of IDs like here is always a positive integer and therefore always evaluates to true, never interfering with the where clause. This only works if some row was actually found, so remember to check affected rows. You can then get the ID in multiple ways.
MySQL last_insert_id()
You can generate sequences without calling LAST_INSERT_ID(), but the
utility of using the function this way is that the ID value is
maintained in the server as the last automatically generated value. It
is multi-user safe because multiple clients can issue the UPDATE
statement and get their own sequence value with the SELECT statement
(or mysql_insert_id()), without affecting or being affected by other
clients that generate their own sequence values.
MySQL mysql_insert_id()
Returns the value generated for an AUTO_INCREMENT column by the
previous INSERT or UPDATE statement. Use this function after you have
performed an INSERT statement into a table that contains an
AUTO_INCREMENT field, or have used INSERT or UPDATE to set a column
value with LAST_INSERT_ID(expr).
The reason for the differences between LAST_INSERT_ID() and
mysql_insert_id() is that LAST_INSERT_ID() is made easy to use in
scripts while mysql_insert_id() tries to provide more exact
information about what happens to the AUTO_INCREMENT column.
PHP mysqli_insert_id()
Performing an INSERT or UPDATE statement using the LAST_INSERT_ID()
function will also modify the value returned by the mysqli_insert_id()
function.
Putting it all together:
$affected_rows = DB::getAffectedRows("
update users set status = 'processing'
where status = 'pending' and last_insert_id(user_id)
limit 1"
);
if ($affected_rows) {
$user_id = DB::getInsertId();
}
(FYI that DB class is here.)
This is the same method as Salman A's answer, but here's the code you actually need to do it.
First, edit your table so that it will automatically keep track of whenever a row is modified. Remove the last line if you only want to know when a row was initially inserted.
ALTER TABLE mytable
ADD lastmodified TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Then, to find out the last updated row, you can use this code.
SELECT id FROM mytable ORDER BY lastmodified DESC LIMIT 1;
This code is all lifted from MySQL vs PostgreSQL: Adding a 'Last Modified Time' Column to a Table and MySQL Manual: Sorting Rows. I just assembled it.
Query :
$sqlQuery = "UPDATE
update_table
SET
set_name = 'value'
WHERE
where_name = 'name'
LIMIT 1;";
PHP function:
function updateAndGetId($sqlQuery)
{
mysql_query(str_replace("SET", "SET id = LAST_INSERT_ID(id),", $sqlQuery));
return mysql_insert_id();
}
It's work for me ;)
SET #uids := "";
UPDATE myf___ingtable
SET id = id
WHERE id < 5
AND ( SELECT #uids := CONCAT_WS(',', CAST(id AS CHAR CHARACTER SET utf8), #uids) );
SELECT #uids;
I had to CAST the id (dunno why)... or I cannot get the #uids content (it was a blob)
Btw many thanks for Pomyk answer!
Hey, I just needed such a trick - I solved it in a different way, maybe it'll work for you. Note this is not a scalable solution and will be very bad for large data sets.
Split your query into two parts -
first, select the ids of the rows you want to update and store them in a temporary table.
secondly, do the original update with the condition in the update statement changed to where id in temp_table.
And to ensure concurrency, you need to lock the table before this two steps and then release the lock at the end.
Again, this works for me, for a query which ends with limit 1, so I don't even use a temp table, but instead simply a variable to store the result of the first select.
I prefer this method since I know I will always update only one row, and the code is straightforward.
ID of the last updated row is the same ID that you use in the 'updateQuery' to found & update that row. So, just save(call) that ID on anyway you want.
last_insert_id() depends of the AUTO_INCREMENT, but the last updated ID not.
My solution is , first decide the "id" ( #uids ) with select command and after update this id with #uids .
SET #uids := (SELECT id FROM table WHERE some = 0 LIMIT 1);
UPDATE table SET col = 1 WHERE id = #uids;SELECT #uids;
it worked on my project.
Further more to the Above Accepted Answer
For those who were wondering about := & =
Significant difference between := and =, and that is that := works as a variable-assignment operator everywhere, while = only works that way in SET statements, and is a comparison operator everywhere else.
So SELECT #var = 1 + 1; will leave #var unchanged and return a boolean (1 or 0 depending on the current value of #var), while SELECT #var := 1 + 1; will change #var to 2, and return 2.
[Source]
If you are only doing insertions, and want one from the same session, do as per peirix's answer. If you are doing modifications, you will need to modify your database schema to store which entry was most recently updated.
If you want the id from the last modification, which may have been from a different session (i.e. not the one that was just done by the PHP code running at present, but one done in response to a different request), you can add a TIMESTAMP column to your table called last_modified (see http://dev.mysql.com/doc/refman/5.1/en/datetime.html for information), and then when you update, set last_modified=CURRENT_TIME.
Having set this, you can then use a query like:
SELECT id FROM table ORDER BY last_modified DESC LIMIT 1;
to get the most recently modified row.
No need for so long Mysql code. In PHP, query should look something like this:
$updateQuery = mysql_query("UPDATE table_name SET row='value' WHERE id='$id'") or die ('Error');
$lastUpdatedId = mysql_insert_id();

Get current auto_increment value

I am doing mysql insert for my table using php.
Autoincrement column name is "link_id"
and "alias" colum is used to make SEO friendly url.
During my insert, I would like to attach link_id value at the end of my alias column.
So I need to know what is the being inserted link_id value.
I do not want to do another query.
mysql_insert_id() does not work, since its using previous query, and not current query.
Thanks
You should use SHOW TABLE STATUS:
$query = mysql_query("SHOW TABLE STATUS LIKE tablename");
$row = mysql_fetch_array($query);
$next_id = $row["Auto_increment"];
It will give you the current status of auto_increment column.
EDITED:
In one query you can do it like this:
INSERT INTO table_schema.table_name(column_name)
VALUES (("SELECT AUTO_INCREMENT
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'table_schema'
AND TABLE_NAME = 'table_name'"))
It will give you the new auto_increment value in the column column_name.
Have you considered a trigger in MySQL? Something like:
DELIMITER //
CREATE TRIGGER `add_alias_id` AFTER INSERT ON `someTable`
FOR EACH ROW BEGIN
UPDATE
`someTable`
SET
`alias` = CONCAT(`alias`,NEW.`link_id`)
WHERE
`link_id` = NEW.`link_id`;
END;
//
DELIMITER ;
EDIT: I was recently working for a company whose flagship software used to assume that max(id) + 1 = next id. The problem is concurrency; it's rare, but two people can get the same id, causing all sorts of chaos. Be extremely careful trying to predict the value.
I handle this type of scenario on the SELECT end.
For Example:
insert into tablename(aliasroot) values('index.php?link_id=');
This would give you for example
In my select I would do 'select concat(aliasroot,link_id) as alias from tablename'
you could use mysql_insert_id() ++, though that won't always be reliable.
what would be better would be to insert the query, then append the current id using CONCAT()

Categories