简体   繁体   中英

MySQL sort 3 columns

I am trying to sort MySQL result from qry_ledger_all_balance and it's working fine, but the problem is I can only sort by PaymentDate .

I want to sort in the order of:

  1. PaymentDate value
  2. Debit value
  3. Credit value

I am unable to do that. I don't know what I am doing wrong. Here is my Table Structure Sample.

+-----------------+-------+--------+---------------------+----------------------------+
|   PaymentCode   | Debit | Credit |     PaymentDate     |         Particular         |
+-----------------+-------+--------+---------------------+----------------------------+
| CTM-41700000008 | 25000 |      0 | 2017-05-15 17:27:28 | Token Money From Customer1 |
| CTM-41700000007 | 12000 |      0 | 2017-05-15 17:26:26 | Token Money From Customer2 |
| CRV-11700000166 | 15000 |      0 | 2016-05-15 17:57:01 | Customer1 Receipt Vourcher |
| EPV-21700000012 |     0 |    150 | 2017-05-15 14:23:26 | Cash Outflow               |
| EPV-21700000004 |     0 |   1110 | 2017-05-15 14:06:48 | Cash Outflow               |
| EAS-41700000001 |     0 |  10000 | 2017-05-15 12:27:47 | Employee Advance Salary    |
+-----------------+-------+--------+---------------------+----------------------------+

Here is my query code in PHP

$branch_sql = "SELECT a.PaymentCode, a.Particular, a.Credit, a.Debit, 
Date(a.PaymentDate) AS PaymentDate, a.BranchID, a.CCode As RefPrint, 
a.RunningBalance, a.OpeningBalance, b.branchname FROM qry_ledger_all_balance AS a 
INNER JOIN tblbranches AS b 
ON a.BranchID = b.branchid 
WHERE DATE_FORMAT(a.PaymentDate, '%Y-%m-%d') >= '$Start_Date' AND
DATE_FORMAT(a.PaymentDate, '%Y-%m-%d') <= '$End_Date' 
ORDER BY a.PaymentDate ASC, a.Debit ASC, a.Credit ASC";

Edit

I suspect you want

 ORDER BY DATE(a.PaymentDate), 
          CASE WHEN a.Debit > 0 THEN 1     /* nonzero debit */
               WHEN a.Credit > 0 THEN 2    /* zero debit, nonzero credit */
               ELSE 3 END,                 /* both zero, both nonzero */
          a.Debit, a.Credit

because if you don't use the DATE() function, MySQL will order by date and time.

By the way, your date selection criteria aren't sargable . This can cause serious performance problems when your tables get big.

Try this instead.

WHERE a.PaymentDate  >= '$Start_Date'
  AND a.PaymentDate  < '$End_Date' + INTERVAL 1 DAY

(Notice the < and the extra day at the end of the range. That will include all records with DATETIME values anytime on the $End_Date . )

If you have an index on a.PaymentDate this will allow that index to be range-scanned.

Your order by clause needs to be slightly more clever. Putting a case statement in your order by will let you create a group like sorting element.

SELECT 
  a.PaymentCode, a.Particular, a.Credit, a.Debit, 
  Date(a.PaymentDate) AS PaymentDate, a.BranchID, 
  a.CCode As RefPrint, a.RunningBalance, 
  a.OpeningBalance, b.branchname 
 FROM qry_ledger_all_balance AS a 
 INNER JOIN tblbranches AS b 
   ON a.BranchID = b.branchid 
 WHERE DATE_FORMAT(a.PaymentDate, '%Y-%m-%d') 
   >= '$Start_Date' 
 AND DATE_FORMAT(a.PaymentDate, '%Y-%m-%d') 
   <= '$End_Date' 
 ORDER BY 
  date(a.PaymentDate) ASC, 
  case 
    when a.Debit > 0 
      then 0
    else 1
  end ASC, 
  case 
    when a.Debit > 0 
      then a.Debit
    else a.Credit
  end ASC

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM