簡體   English   中英

如何在一列中獲取所有值mysql的總和和減去

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM