Increase and decrease row value by 1 in MySQL - php

Hi I have a MySQL database table "points" the user can click a button and a point should be removed from their account, the button they pressed has an ID of another user, therefore their account must increase by one.
I have it working in jQuery and checked the varibles/posts in Firebug, and it does send the correct data, such as:
userid= 1
posterid = 4
I think the problem is with my PHP page:
<?php
include ('../functions.php');
$userid=mysql_real_escape_string($_POST['user_id']);
$posterid=mysql_real_escape_string($_POST['poster_id']);
if (loggedin())
{
include ('../connection.php');
$query1 = "UPDATE `points` SET `points` = `points` - 1 WHERE `userID` = '$userid'";
$result1=mysql_query($query1);
$query2 = "UPDATE `points` SET `points` = `points` + 1 WHERE `userID` = '$posterid'";
$result2=mysql_query($query2);
if ($result1 && result2)
{
echo "Successful";
return 1;
}
else
{
echo mysql_error();
return 0;
}
}
?>
Any ideas? Thanks :)

Two queries to increase/decrease field value are not necessary:
UPDATE table SET field = field + 1 WHERE id = 1
is a perfectly valid query as you can see next:
mysql> describe points;
+--------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+-------+
| uid | int(11) | NO | PRI | NULL | |
| points | int(11) | YES | | 0 | |
+--------+---------+------+-----+---------+-------+
2 rows in set (0.05 sec)
mysql> insert into points VALUES (1,0),(2,0);
Query OK, 2 rows affected (0.14 sec)
mysql> select * from points;
+-----+--------+
| uid | points |
+-----+--------+
| 1 | 0 |
| 2 | 0 |
+-----+--------+
2 rows in set (0.05 sec)
mysql> update points set points = points+1 where uid = 1;
Query OK, 1 row affected (0.27 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from points;
+-----+--------+
| uid | points |
+-----+--------+
| 1 | 1 |
| 2 | 0 |
+-----+--------+
2 rows in set (0.00 sec)
Having that tested, are you sure you get into your if (loggedin()) clause?
I have to agree with KM, would be nice to see output of echo $query1; or echo $query2;

Here is the example query, tested by me and it is working 100%
$query="UPDATE table_name SET `hit_count`=(`hit_count`+1) WHERE `id` = '1'";

update table_name set col_name=col_name+1 where sqId = 12
But if your col_name by default value is null or empty it never works, so make sure that col_name default value is 0 or any integer value.

update 'tablename' set 'columnname1'='columnname1' + 1 where 'columnname2'='value';
eg: update students set englishmarks=englishmarks + 1 where name='Rahul';
Edit:(Explanation)
"UPDATE" keyword is used to update a vaule in the table. Here I am updating a value in the table "students". "SET" keyword updating the english marks by 1(just like in C language, how we increase the value of an integer, i=i+1) and condidtion is given where name is "Rahul".
So englishmarks of Rahul are incremented by 1

In laravel Migration do:
\DB::statement('SELECT #pos:=0;');
\DB::statement('UPDATE users SET company_id = ( SELECT #pos := #pos + 1 ) WHERE `id` = '1';');
If want to change all records, remove the WHERE id = '1'
It will insert number increment to your records like:
+-----+------------+
| id | company_id |
+-----+------------+
| 1 | 1 |
| 12 | 2 |
| 23 | 3 |
+-----+------------+

Related

Trigger- Update columns in one table on inserting in another table

So, I have 2 tables.
One is books, that has the following fields.
accno(Accession number), name(book name), status(Issued/Not Issued)
Second is total, that has the following fields.
name(book name), count(Number of books that are 'Not Issued' in the books table
I have a form that adds books in the books table, and the default status is 'Not Issued'.
I also have a form that issued books i.e. it changes the status to 'Issued'.
And I have a form that returns the books i.e. it changes the status back to 'Not Issued'.
I'm looking for a trigger that updates the count in the total table everytime the bookstable is updated. Count is the number of books that are available(Not Issued) in the books table, and it is different for different books(book names).
I am totally new to triggers. I have looked arond, but I can't seem to figure a way to implement this.
Any help is appreciated. Thank you.
Looks like its an inventory system, so every time a new book comes into the library you store the inventory number into the total table and when a book is issued against the accnum the inventory is decreased by one and then its returned its increased by one.
In this case the following trigger should do the job
delimiter //
create trigger book_available after update on books
for each row
begin
if new.status = 'Issued' then
update total set `count` = `count` - 1 where name = new.book_name ;
else
update total set `count` = `count` + 1 where name = new.book_name ;
end if ;
delimiter ;
Here is a test case
mysql> select * from books ;
+--------+-----------+------------+
| accnum | book_name | status |
+--------+-----------+------------+
| 1 | AA | Not Issued |
| 2 | AA | Issued |
| 3 | BB | Not Issued |
+--------+-----------+------------+
3 rows in set (0.00 sec)
mysql> select * from total ;
+------+-------+
| name | count |
+------+-------+
| AA | 20 |
| BB | 30 |
+------+-------+
2 rows in set (0.00 sec)
mysql> delimiter //
mysql> create trigger book_available after update on books
-> for each row
-> begin
-> if new.status = 'Issued' then
-> update total set `count` = `count` - 1 where name = new.book_name ;
-> else
-> update total set `count` = `count` + 1 where name = new.book_name ;
-> end if ;
-> end ;//
Query OK, 0 rows affected (0.13 sec)
mysql> delimiter ;
mysql> update books set status = 'Issued' where accnum = 1 ;
Query OK, 1 row affected (0.08 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from total ;
+------+-------+
| name | count |
+------+-------+
| AA | 19 |
| BB | 30 |
+------+-------+
2 rows in set (0.00 sec)
mysql> update books set status = 'Not Issued' where accnum = 1 ;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from total ;
+------+-------+
| name | count |
+------+-------+
| AA | 20 |
| BB | 30 |
+------+-------+
2 rows in set (0.00 sec)

MySQL advanced UPDATE query

I want to set an image as a cover for the album and i do it by choosing it from a radio input that is in a do-while loop. I have put in images table a field named is_cover that takes 1 if the image is set as cover ,or 0 if not.
<input type="radio" name="cover" value="<?php echo $row_images['image_id']; ?>" <?php if($row_images['is_cover'] == 1){ echo "checked=\"checked\""; } ?> />
My question is how can i perform an update query that sets all images is_cover field to 0 and only the image selected gets the value 1.
What i'm trying to say is how can i achieve this:
$is_cover = $_POST['cover'];
$query = "
UPDATE images
SET is_cover = 1
WHERE image_id = {$is_cover}
AND SET is_cover = 0
WHERE image_id <> {$is_cover}
";
This should do the trick for you:
UPDATE images SET is_cover = CASE WHEN image_id = {$is_cover} THEN 1 ELSE 0 END;
From my test:
mysql> select * from first;
+------+-------+
| id | title |
+------+-------+
| 1 | aaaa |
| 2 | bbbb |
| 3 | cccc |
| 4 | NULL |
| 6 | ffff |
+------+-------+
5 rows in set (0.01 sec)
mysql> update first set title = case when id > 4 then 'gggg' else title end;
Query OK, 1 row affected (0.01 sec)
Rows matched: 5 Changed: 1 Warnings: 0
mysql> select * from first;
+------+-------+
| id | title |
+------+-------+
| 1 | aaaa |
| 2 | bbbb |
| 3 | cccc |
| 4 | NULL |
| 6 | gggg |
+------+-------+
5 rows in set (0.00 sec)
You can run 2 Queries here one to set them all to 0 and then setting the one you selected to 1
Execute these 2 queries:
$query = "UPDATE images SET is_cover = 0 WHERE image_id <> {$is_cover}";
$query = "UPDATE images SET is_cover = 1 WHERE image_id = {$is_cover}";
The first query sets all is_cover to zero. The second query sets is_cover to 1 for the selected image.

Simple UPDATE SQL Query

I'm doing a work for a client but since I haven't been using PHP/MySQL for a while I forgot some simple things, hope you can help me out.
I have the following SQL table:
ID (non-null, autoincrement) | credit (int)
My query should put the whole "credit" column to 0 except for the row that has the higher ID.
So I would do:
UPDATE $table SET credit = 0 WHERE... ?
Thanks in advance for any help :)
UPDATE $table SET credit = 0 WHERE ID > $ID
Will update any rows that have and ID greater than the variable $ID
If you only want to update the row with the maximum ID then use:
UPDATE $table SET credit = 0 WHERE ID = (select max(id) from $table)
Edit: As Eggyal correctly points out MySQL doesn't like a subquery on the same table as an update - but you can get around it nicely:
UPDATE $table
SET credit = 0
WHERE
credit='$credit'
AND statid='$statid'
AND userid='$userid'
AND ID = (select ID from (SELECT MAX(ID)as ID from $table) a)
And examples from my console:
mysql> select * from first;
+------+-------+
| id | title |
+------+-------+
| 1 | aaaa |
| 2 | bbbb |
| 3 | cccc |
| 4 | NULL |
| 6 | eeee |
+------+-------+
5 rows in set (0.00 sec)
mysql> update first set title='ffff' where id=(select max(id) from first);
ERROR 1093 (HY000): You can't specify target table 'first' for update in FROM clause
mysql> update first set title='ffff' where id=(select ID from (select max(id) as ID from first) a);
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from first;
+------+-------+
| id | title |
+------+-------+
| 1 | aaaa |
| 2 | bbbb |
| 3 | cccc |
| 4 | NULL |
| 6 | ffff |
+------+-------+
5 rows in set (0.00 sec)
Note: As the subquery within a subquery trick unlocks the original table, it is a good idea to run this within a transaction - if the table is unlocked from a query, it might have changed by the time it is updated - so it will be a good idea to use this type of query within a transaction.

MySQL signed Order By on integer zero issue

I currently have a signed integer set in a MyISAM table,
The query is like:
SELECT * from some_view ORDER BY value DESC, dateAdded DESC
I'm getting this order:
1
2
-1
-2
0
0
The zero values aren't seen as +/- but I need them to be greater than a negative value!!!
This is my actual query:
SELECT * FROM vw_answer sa left join vw_answer_votes av on av.answerID = sa.id WHERE sa.id = 77 ORDER BY av.vote, dateAdded
I have the following:
tbl_users
tbl_solutions - Indexes tbl_users.id as authorID
tbl_solution_answers - Indexes tbl_solutions.id as solutionID
tbl_solution_answer_votes - Indexes tbl_users.id as voterID and tbl_solution_answers
as answerID
tbl_solution_answer_votes only has one none indexed column which contains -1 or 1 depending on the vote cast by a user. This is a signed integer.
my view when I select answers selects tbl_solution_answers and the sum(tbl_solution_answer_votes.vote)
It all works, except the ordering on signed integer.
Edit: Values in the votes table only exist if a user has voted else it simply doesn't exist. I need something like this I think:
SELECT * FROM tbl_answers sa right join vw_answer_votes av on av.answerID = sa.id
ORDER BY av.vote > 0 desc, av.vote IS NULL, av.vote < 0 desc, dateAdded DESC
You are ordering on two fields, value and dateadded, try taking out your date added.
create table order_by_neg_test
(`id` int(11) unsigned not null auto_increment,
`value` int(11) signed not null,
primary key (`id`)) engine=myisam default charset=utf8;
I inserted some random values and here are the results:
# No order
mysql> select * from order_by_neg_test;
+----+-------+
| id | value |
+----+-------+
| 1 | 45 |
| 2 | 1 |
| 3 | 0 |
| 4 | -1 |
| 5 | 17 |
| 6 | 27 |
| 7 | -1 |
+----+-------+
7 rows in set (0.00 sec)
# With an order
mysql> select * from order_by_neg_test order by value desc;
+----+-------+
| id | value |
+----+-------+
| 1 | 45 |
| 6 | 27 |
| 5 | 17 |
| 2 | 1 |
| 3 | 0 |
| 4 | -1 |
| 7 | -1 |
+----+-------+
7 rows in set (0.00 sec)
Notice in the order, 0 > -1.
You should try
ORDER BY CAST(value AS SIGNED) DESC
if your view screwed up the type

Is there an improvement for my sql query?

is there any way to remove the MAX with something else, maybe the ASC LIMIT 1 to decrease database throttling? My query gets the maximum id and adds 1 to it.
This is my query:
$query = 'SELECT MAX(ID) +1 as maxidpost
FROM wp_posts';
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)) {
echo 'p='. $row['maxidpost'];
}
mysql_close();
What does the database tell you about your query? If id is indexed then
mysql> explain select max(id) + 1 from times;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
1 row in set (0.18 sec)
mysql> explain select id from times order by id ASC limit 1;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | times | index | NULL | PRIMARY | 4 | NULL | 1 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)
This is fine. adding limit 1 isn't going to give any noticeable performance improvements.
This shouldn't cause any kind of issues, are you having problems with this particular query?
The SQL MAX() function will automatically look for just one result. There's no need of LIMIT it in any way. If you want to improve that query try setting ID as index.
SELECT ID + as maxidpost FROM wp_posts ORDER BY ID DESC LIMIT 1;
or If the table have Auto_increment ID
SHOW TABLE STATUS LIKE 'wp_posts';
There should be a field called Auto_increment which should be exactly MAX(ID) + 1;

Categories