[英]how to get all value mysql sum and subtract in one column
我為會計應用程序創建了一個API。 我在一欄中有收入和支出。 如何將所有收入和支出相加並減去?
這是我的代碼:
private function list_recap() {
if($this->get_request_method() != "GET") {
$this->response('', 406);
}
$year = $this->_request['year'];
$month = $this->_request['month'];
$sqlPlus = $this->db->query("SELECT SUM(nominal)
FROM lap_keuangan
WHERE YEAR(tanggal) = '$year'
AND MONTH(tanggal) = '$month'
AND kategori = 1");
$sqlMin = $this->db->query("SELECT SUM(nominal)
FROM lap_keuangan
WHERE YEAR(tanggal) = '$year'
AND MONTH(tanggal) = '$month'
AND kategori = -1");
$result = array();
while($rowPlus = $sqlPlus->fetch(PDO::FETCH_ASSOC)) {
$plus = $result[] = $rowPlus;
}
while($rowMin = $sqlMin->fetch(PDO::FETCH_ASSOC)) {
$minus = $result[] = $rowMin;
}
$this->response($this->json($result), 200);
}
使用一個SELECT語句檢索“加”,“減”和“總計”。 我們可以使用條件聚合。 給定WHERE子句中的一個條件,該條件可以保證kategori
的值為1或-1,我們可以將nominal
乘以該值,然后將其與SUM相加。
在此過程中,我們應該清除SQL Injection漏洞。 我們從不希望在SQL文本中包含潛在的不安全值。
https://www.owasp.org/index.php/SQL_Injection
我們要么在包含值之前適當地對它們進行轉義,要么使用帶有綁定占位符的預處理語句。 (這並不難;沒有任何不做的有效借口。)
為了提高性能,我們希望在裸列上有條件,而不是在表達式中包裝列。 如果tanggal
是DATE,DATETIME或TIMESTAMP數據類型,我們可以在該列上指定條件作為值的范圍。 (如果合適的索引可用,這允許MySQL使用范圍掃描操作,而不是對表中的每一行求值。)
我可能會將$year
和$month
值轉換為yyyy-mm-01格式的字符串,然后將該日期字符串傳遞到查詢中。 但是我們可以將$ year和$ month值傳遞給查詢,並讓MySQL將其轉換為日期。
像這樣:
# static SQL text (no variable interpolation) mitigates SQL Injection
$sql =
"SELECT SUM( k.nominal * IF(k.kategori= 1 ,1,0) ) AS kat_plus
, SUM( k.nominal * IF(k.kategori= -1 ,1,0) ) AS kat_minus
, SUM( k.nominal * k.kategori ) AS kat_total
FROM lap_keuangan k
WHERE k.tanggal >= STR_TO_DATE(CONCAT( ? ,'-', ? ,'-01'),'%Y-%m-%d')
AND k.tanggal < STR_TO_DATE(CONCAT( ? ,'-', ? ,'-01'),'%Y-%m-%d') + INTERVAL 1 MONTH
AND k.kategori IN (-1,1)";
# prepare
$sth = $this->db->prepare($sql);
使用bindValue
為每個綁定占位符提供值並執行
# execute
$sth->bindValue(1, $year ,PDO::PARAM_STR);
$sth->bindValue(2, $month ,PDO::PARAM_STR);
$sth->bindValue(3, $year ,PDO::PARAM_STR);
$sth->bindValue(4, $month ,PDO::PARAM_STR);
$sth->execute();
或使用位置綁定,我們可以跳過bindValue並只傳遞一個數組來執行:
# execute
$sth->execute(array($year,$month,$year,$month));
然后獲取該行,並訪問數組成員
$row = $sth->fetch(PDO::FETCH_ASSOC);
$kat_plus = $row['kat_plus'];
$kat_minus = $row['kat_minus'];
$kat_total = $row['kat_total'];
如果未/未配置PDO引發異常,即
$this->$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
然后添加對每個PDO函數調用(准備,執行,獲取)成功/失敗的檢查,並處理代碼中的錯誤。
您可以使用CASE-THEN-ELSE
構造,嘗試執行以下SQL語句:
SELECT
SUM(CASE WHEN kategori = 1 THEN nominal ELSE 0 END) -
SUM(CASE WHEN kategori = -1 THEN nominal ELSE 0 END)
FROM lap_keuangan
WHERE
YEAR(tanggal) = '$year'
AND MONTH(tanggal) = '$month'
AND kategori = 1
PS:
您的代碼容易受到SQL Injection攻擊。 您不得使用字符串串聯傳遞SQL查詢參數。 請改用PDO
並綁定參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.