MySQL INSERT / SELECT子查询语法

时间:2011-02-02 17:36:10

标签: mysql select insert subquery

无法绕过这个的正确语法。下面是我的查询,我的子查询的简单英语解释,在我认为我希望它执行的地方。

mysql_query("INSERT INTO donations(
            tid,
            email,
            amount,
            ogrequest,
            total
            )
            VALUES (
                '".esc($p->ipn_data['txn_id'])."',
                '".esc($p->ipn_data['pay_email'])."',
                ".(float)$amount.",
                '".esc(http_build_query($_POST))."',

            Here I want to select the row with the max date, get the value of the "total" column in that row, and add $amount to that value to form the new "total" for my newly inserted row.

            )");

任何人都可以帮助兄弟吗?

4 个答案:

答案 0 :(得分:3)

真正的答案是您不应该将总数存储在此表的列中。它实际上并不是任何有用的信息。您应该存储的是当前日期,然后通过SUM和GROUP BY计算总数。如果这是您需要经常访问的内容,请将值缓存在其他位置。

为什么你需要在最后一行之前的任何行中的总数?这只是浪费的数据,可以从表中轻松重新生成。

为什么要将总数存储在此列中。这些数据对您的架构有什么价值?这里要注意的重要一点是,总数不是单个交易的属性。总数是各个交易的聚合子集的属性。

另外 - 如果不是,请确保在MySQL中使用DECIMAL而不是FLOAT作为货币列类型。 FLOAT值可能会导致舍入错误,具体取决于您正在做什么,这是涉及金钱时没有理由冒险的。

答案 1 :(得分:0)

我无法访问MySQL服务器以验证我创建的内容,但请尝试以下操作:

INSERT INTO donations
(
    tid,
    email,
    amount,
    ogrequest,
    total
)
SELECT
    '".esc($p->ipn_data['txn_id'])."',
    '".esc($p->ipn_data['pay_email'])."',
    ".(float)$amount.",
    '".esc(http_build_query($_POST))."',
    total + '".esc($amount)."'
FROM
ORDER BY date DESC
LIMIT 1

我没有使用直接的“INSERT INTO(...)VALUES(...)”,而是使用了“INSERT INTO(...)SELECT ...”。 SELECT语句检索具有最高日期的行(ORDER BY日期DESC LIMIT 1),然后访问总字段并添加$ amount的值。

答案 2 :(得分:0)

mysql_query("INSERT INTO donations(
            tid,
            email,
            amount,
            ogrequest,
            total
            )
            VALUES (
                '".esc($p->ipn_data['txn_id'])."',
                '".esc($p->ipn_data['pay_email'])."',
                ".(float)$amount.",
                '".esc(http_build_query($_POST))."',
                (select max(total) from donations) + ".(float)$amount."




            )");

答案 3 :(得分:0)

您的子查询可能如下所示:

SELECT total
FROM donations 
WHERE tid = <x>
ORDER BY date DESC
LIMIT 1

这当然要求您的表格中有date列。如果你运行这个(没有你已有的外部查询),它应该返回一行,单列结果包含tid =&lt; x&gt;的最新总数值。

如果还没有txn =&lt; x&gt;的行在表中,它显然将根本不返回任何行。当用作INSERT语句的子查询时,您应该检查NULL并将其替换为数字0(零)。这就是IFNULL()可以为你做的事情。

将此与您已有的结合起来:

mysql_query("INSERT INTO donations(
            tid,
            email,
            amount,
            ogrequest,
            total
            )
            VALUES (
                '".esc($p->ipn_data['txn_id'])."',
                '".esc($p->ipn_data['pay_email'])."',
                ".(float)$amount.",
                '".esc(http_build_query($_POST))."',
                IFNULL(SELECT total
                 FROM donations
                 WHERE id = ".esc(p->ipn_data[txn_id']."
                 ORDER BY date DESC 
                 LIMIT 1),0) + ".esc($p->ipn_data['value']
            )");