RNK
RNK

Reputation: 5792

mysql: group by and get latest record

I have query like this:

SELECT cus_id, ROUND(SUM(credit_in)-SUM(credit_out), 2) as balance, date_added
FROM `customer_wallet`
GROUP BY cus_id

It will get the customer's balance (unique customers). I want to modify this if balance is in minus then it'll come and I want latest date (date_added).

I tried by doing this:

SELECT cus_id, ROUND(SUM(credit_in)-SUM(credit_out), 2) as balance, date_added
FROM `customer_wallet`
GROUP BY cus_id
ORDER BY date_added

But, it's giving sorted records after getting all result. I want latest record for individual customer.

Let me know if you need more info or schema. Thanks.

I can check records with minus balance in php as well. But, it'll be great if I can do it in query itself.

Upvotes: 1

Views: 203

Answers (4)

JMariña
JMariña

Reputation: 324

So I am making some assumptions here (I also saw the sql tag, so I am hoping an answer in sql will be helpful):

You have a customer table: cust_id is the primary key, and a given customer has only one row dedicated to them

You have a wallet table with credits. cust_id is a foreign key, and any customer can have multiple rows in this table. WalletId is the primary key in this table, and the most recent transactions have the highest number

It will be tough to do this while returning just cust_id. If you aren't averse to returning 1 extra column this can be done easily (the walletid). You just need to add import date to the group clause, and utilize the max function against walletid.

SELECT cus_id, MAX(walletid), ROUND(SUM(credit_in)-SUM(credit_out), 2) as balance, date_added
FROM customer_wallet
GROUP BY IssuerId, date_added
ORDER BY date_added

Upvotes: 0

Hogan
Hogan

Reputation: 70513

You need to use an aggregate function to select the most recent date -- I believe the default is for mysql to just pick a random value for that column.

SELECT cus_id, 
       ROUND(SUM(credit_in)-SUM(credit_out), 2) as balance, 
       max(date_added) as most_recent
FROM `customer_wallet`
Having SUM(credit_in) < SUM(credit_out)
GROUP BY cus_id

Upvotes: 1

mucio
mucio

Reputation: 7119

MYSQL by default doesn't force you to put all columns which are not included in aggregated function in the Group By clause. This can return strange results.

Try the following query.

  SELECT cus_id, 
         ROUND(SUM(credit_in)-SUM(credit_out), 2) as balance, 
         max(date_added) latest_transaction_date
    FROM `customer_wallet`
GROUP BY cus_id
  HAVING ROUND(SUM(credit_in)-SUM(credit_out), 2) < 0

If you want to read more about the Group By in MySQL you can check this blog post: Debunking GROUP BY myths. It's quite old, but still interesting if you are new to MySQL.

Upvotes: 1

ABrowne
ABrowne

Reputation: 1604

It is unclear from your question, but I assuming you want the negative balances for individuals and the date of their last transaction.

SELECT cus_id, ROUND(SUM(credit_in)-SUM(credit_out), 2) as balance, max(date_added) as last_date
FROM `customer_wallet`
HAVING ROUND(SUM(credit_in)-SUM(credit_out) < 0
GROUP BY cus_id
ORDER BY last_date

If you don't want just the negative balances then use this:

SELECT cus_id, ROUND(SUM(credit_in)-SUM(credit_out), 2) as balance, max(date_added) as last_date
FROM `customer_wallet`
GROUP BY cus_id
ORDER BY last_date

Upvotes: 0

Related Questions