mysql表的最佳更新查询

时间:2009-12-29 14:00:57

标签: php mysql

我有一个文件托管网站,我为每个用户提供了一个独特的下载点。

我的桌子样本
Sample table

这些积分可由用户兑换。因此,例如,如果用户兑换100点而不是最佳查询,则减少每行可用点数,直至减少100点。

谢谢。

5 个答案:

答案 0 :(得分:3)

您应该为此创建两个表:

Table files
- id
- name
- size

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

插入新文件:

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

现在你可以给一个负面或正面的文件:

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

您可以选择总分数:

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

答案 1 :(得分:2)

好吧,那么,这是我会做的SQL-dumb方式。希望SQL大师能够找到更好的解决方案。 注意:这是纯伪代码;基于此编写自己的代码 - 它不会开箱即用。

$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

答案 2 :(得分:1)

看起来你只需要一个简单的更新语句,并允许你更新行,如果它超过100不更新它。

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

这将检查点是否高于100,如果是,则更新语句将不返回任何结果。如果该值小于100,则它将更新表并返回已更新的行数。

答案 3 :(得分:0)

只需在用户表格中添加一个包含已兑换积分金额的列。这对你来说是一个可行的解决方案吗?

答案 4 :(得分:0)

这是一个纯粹的SQL解决方案,但我警告你(a)这是未经测试的,(b)它只是一个概念。

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;