MySQL INSERT/SELECT子查询语法
只是无法围绕这一个正确的语法包裹我的头。下面是我的查询,对我的子查询进行简单的英语解释,并在我认为我希望它执行的地方。MySQL INSERT/SELECT子查询语法
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.
)");
任何人都可以帮忙吗?
真正的答案是,你不应该在这个表中的列存储总量。这实际上没有任何有用的信息。你应该存储的是当前日期,然后通过SUM和GROUP BY计算总数。如果这是您需要经常访问的内容,请将值缓存到其他位置。
为什么你需要在最后一行之前的任何行中的总数?这只是浪费的数据,并且可以从表格中轻松重新生成。
为什么要将总数存储在此列中。这些数据为您的架构添加了什么价值?这里要注意的重要一点是,总数不是单个交易的财产。总数是个别事务的聚集子集的属性。
另外 - 确保你在MySQL中使用DECIMAL而不是FLOAT作为你的货币列类型,如果你不是。 FLOAT值可能会导致舍入错误取决于您正在做什么,这是在涉及金钱时没有理由冒险的事情。
我没有访问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 date DESC LIMIT 1),然后访问总字段并添加$ amount的值。
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."
)");
你的子查询看起来是这样的:
SELECT total
FROM donations
WHERE tid = <x>
ORDER BY date DESC
LIMIT 1
当然,这需要你在你的表中的列date
。如果你运行这个(没有你已经有的外部查询),它应该返回一行,单列结果包含tid = <x>的最新值。
如果表格中没有txn = <x>的行,那么它显然不会返回任何行。当用作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']
)");
你是对的。我这样做的唯一原因是因为我需要经常访问它,并且想知道在数百行中不断计算SUM的开销。我想,不必遍历所有这些行,我可以从最后一行获得单个值,这对数据库来说应该不那么紧张。你会推荐什么技术来缓存它? – Jon 2011-02-02 17:57:25