2011-02-02 159 views
1

只是無法圍繞這一個正確的語法包裹我的頭。下面是我的查詢,對我的子查詢進行簡單的英語解釋,並在我認爲我希望它執行的地方。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. 

      )"); 

任何人都可以幫忙嗎?

回答

3

真正的答案是,你不應該在這個表中的列存儲總量。這實際上沒有任何有用的信息。你應該存儲的是當前日期,然後通過SUM和GROUP BY計算總數。如果這是您需要經常訪問的內容,請將值緩存到其他位置。

爲什麼你需要在最後一行之前的任何行中的總數?這只是浪費的數據,並且可以從表格中輕鬆重新生成。

爲什麼要將總數存儲在此列中。這些數據爲您的架構添加了什麼價值?這裏要注意的重要一點是,總數不是單個交易的財產。總數是個別事務的聚集子集的屬性。

另外 - 確保你在MySQL中使用DECIMAL而不是FLOAT作爲你的貨幣列類型,如果你不是。 FLOAT值可能會導致舍入錯誤取決於您正在做什麼,這是在涉及金錢時沒有理由冒險的事情。

+0

你是對的。我這樣做的唯一原因是因爲我需要經常訪問它,並且想知道在數百行中不斷計算SUM的開銷。我想,不必遍歷所有這些行,我可以從最後一行獲得單個值,這對數據庫來說應該不那麼緊張。你會推薦什麼技術來緩存它? – Jon 2011-02-02 17:57:25

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 date DESC LIMIT 1),然後訪問總字段並添加$ amount的值。

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." 




      )"); 
0

你的子查詢看起來是這樣的:

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'] 
      )");