简体   繁体   中英

Best update query for mysql table

I have a file hosting site where I provide a point for every unique download to user.

Sample of my table
样品表

These points can be redeemed by user. So for example if a user redeems 100 points than what is the best query to reduce points available from each row till 100 points are reduced.

Thank You.

You should create two tables for this:

Table files
- id
- name
- size

Table points
- id
- file_id
(- user)
- points

Insert a new file:

INSERT INTO files (name, size) VALUES ('kat92a.jpg', 105544); // New file with ID 1

Now you can give points to a file, negative or positive:

INSERT INTO points (file_id, points) VALUES (1, 100); //Positive points
INSERT INTO points (file_id, points) VALUES (1, -10); //Negative points

And you can select the total number of points:

SELECT 
    files.name, 
    files.size, 
    (SELECT sum(points) FROM points WHERE file_id = 1) AS points 
FROM files
WHERE id = 1 

Alright, then, here's the SQL-dumb way I would do it. Hopefully an SQL guru will come around with a better solution. Note: This is pure pseudocode; write your own code based on this--it's not going to work out of the box.

$total_to_deduct = 100;

// Each time, get the row with the highest points
$top_points_query = "SELECT id, points FROM my_table ORDER BY points DESC LIMIT 1;"

do {
  $result = do_query($top_points_query);

  if($result) {
    // I'm assuming you don't want to deduct more points from a row than it has
    $num_to_deduct = min($result['points'], $total_to_deduct);

    // Now deduct the points from the row we got earlier
    $update_query = "UPDATE my_table SET points = points - $num_to_deduct
                     WHERE id = $result['id']";

    if(do_query($update_query)) {
      $total_to_deduct -= $num_to_deduct;
    }
  }
} while($total_to_deduct > 0); // If we still have points to deduct, do it again

Seems like you just need a simple update Statement and allows you to update the row and if it's more than 100 not update it.

update table set points = if( (points+<VALUE>) <= 100,points+<VALUE>,points) where id = <FILE ID>  

This will check to see if the points is higher than 100, if it is then the update statement will just return no results. If the value is less than 100, then it will update the table and give you back the amount of rows that were updated.

Just add a column in your user table with the amount of redeemed points. Is that a viable solution for you?

Here is a pure SQL solution, but I warn you that (a) this is untested and (b) it's just a concept.

DECLARE curs CURSOR FOR
    SELECT
        id,
        points,
    FROM
        points
    WHERE
        points > 0;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET remPoints = 0;
OPEN curs;

SET remPoints = 100; /* modify this value, probably in your app */

REPEAT
    FETCH curs INTO cId, cPoints;

    IF remPoints >= cPoints THEN
        UPDATE points SET points = 0 WHERE id = cId;
    ELSE
        UPDATE points SET points = points - remPoints WHERE id = cId;
    END IF;
    SET remPoints = remPoints - cPoints;
UNTIL remPoints <= 0;

CLOSE curs;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM