1831. Maximum Transaction Each Day
Problem
In this problem, we are given a table Transactions
with the following columns: transaction_id
, day
, and amount
.
Our task is to write an SQL query that reports the transaction IDs with the maximum amount for their respective days. If multiple transactions have the same amount on the same day, include all of them. The result should be sorted in ascending order by transaction_id
.
Example
Consider the following Transactions
table:
+----------------+--------------------+--------+ | transaction_id | day | amount | +----------------+--------------------+--------+ | 8 | 2021-4-3 15:57:28 | 57 | | 9 | 2021-4-28 08:47:25 | 21 | | 1 | 2021-4-29 13:28:30 | 58 | | 5 | 2021-4-28 16:39:59 | 40 | | 6 | 2021-4-29 23:39:28 | 58 | +----------------+--------------------+--------+
The expected result table would be:
+----------------+
| transaction_id |
+----------------+
| 1 |
| 5 |
| 6 |
| 8 |
+----------------+
Here's the walk through for the example above:
- "2021-4-3" has only one transaction with ID 8, so we add 8 to the result table.
- "2021-4-28" has two transactions with IDs 5 and 9. The transaction with ID 5 has an amount of 40, while the transaction with ID 9 has an amount of 21. We only include the transaction with ID 5 as it has the maximum amount this day.
- "2021-4-29" has two transactions with IDs 1 and 6. Both transactions have the same amount of 58, so we include both in the result table.
Finally, the result table is sorted by transaction_id
.
Approach
To solve this problem, we can use the following approach:
- Select the date (without time) for each transaction and group transactions by day.
- For each day, find the transaction(s) with the maximum amount.
- Order the result table by
transaction_id
.
Solution in SQL
We can implement this approach using SQL:
WITH daily_transactions AS (
SELECT transaction_id, DATE(day) AS date, amount
FROM Transactions
)
SELECT transaction_id
FROM daily_transactions
WHERE (date, amount) IN (
SELECT date, MAX(amount)
FROM daily_transactions
GROUP BY date
)
ORDER BY transaction_id;
Explanation
- We first create a Common Table Expression (CTE)
daily_transactions
where we store thetransaction_id
, date (without time), andamount
of each transaction. - Next, we select
transaction_id
from thedaily_transactions
table, where the(date, amount)
tuple is in the result of finding the maximum amount for each date. - Finally, we order the result table by
transaction_id
.## Solutions in Python, JavaScript and Java
Normally, SQL problems should be solved using SQL queries. However, if you need to implement it in a programming language, you can do that with the following code snippets for Python, JavaScript, and Java.
Python
from collections import defaultdict
import datetime
def max_transactions(transactions):
daily_transactions = defaultdict(list)
for transaction in transactions:
transaction_id, day, amount = transaction
date = day.date()
daily_transactions[date].append((transaction_id, amount))
result = []
for date_transactions in daily_transactions.values():
max_amount = max(transaction[1] for transaction in date_transactions)
max_transactions = [transaction[0] for transaction in date_transactions if transaction[1] == max_amount]
result.extend(max_transactions)
result.sort()
return result
transactions = [
(8, datetime.datetime(2021, 4, 3, 15, 57, 28), 57),
(9, datetime.datetime(2021, 4, 28, 8, 47, 25), 21),
(1, datetime.datetime(2021, 4, 29, 13, 28, 30), 58),
(5, datetime.datetime(2021, 4, 28, 16, 39, 59), 40),
(6, datetime.datetime(2021, 4, 29, 23, 39, 28), 58),
]
print(max_transactions(transactions))
JavaScript
function max_transactions(transactions) {
const daily_transactions = {};
transactions.forEach(([transaction_id, day, amount]) => {
const date = day.toISOString().substring(0, 10);
if (!daily_transactions[date]) daily_transactions[date] = [];
daily_transactions[date].push([transaction_id, amount]);
});
const result = [];
Object.values(daily_transactions).forEach(date_transactions => {
const max_amount = Math.max(...date_transactions.map(transaction => transaction[1]));
const max_transactions = date_transactions.filter(transaction => transaction[1] === max_amount).map(transaction => transaction[0]);
result.push(...max_transactions);
});
result.sort((a, b) => a - b);
return result;
}
const transactions = [
[8, new Date('2021-04-03T15:57:28'), 57],
[9, new Date('2021-04-28T08:47:25'), 21],
[1, new Date('2021-04-29T13:28:30'), 58],
[5, new Date('2021-04-28T16:39:59'), 40],
[6, new Date('2021-04-29T23:39:28'), 58],
];
console.log(max_transactions(transactions));
Java
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MaxTransactions {
public static List<Integer> max_transactions(List<Object[]> transactions) {
Map<LocalDate, List<Object[]>> daily_transactions = new HashMap<>();
for (Object[] transaction : transactions) {
Integer transaction_id = (Integer) transaction[0];
LocalDateTime day = (LocalDateTime) transaction[1];
Integer amount = (Integer) transaction[2];
LocalDate date = day.toLocalDate();
daily_transactions.putIfAbsent(date, new ArrayList<>());
daily_transactions.get(date).add(new Object[]{transaction_id, amount});
}
List<Integer> result = new ArrayList<>();
for (List<Object[]> date_transactions : daily_transactions.values()) {
int max_amount = date_transactions.stream().mapToInt(transaction -> (int) transaction[1]).max().orElse(0);
date_transactions.stream()
.filter(transaction -> (int) transaction[1] == max_amount)
.forEach(transaction -> result.add((Integer) transaction[0]));
}
result.sort(Integer::compareTo);
return result;
}
public static void main(String[] args) {
List<Object[]> transactions = List.of(
new Object[]{8, LocalDateTime.of(2021, 4, 3, 15, 57, 28), 57},
new Object[]{9, LocalDateTime.of(2021, 4, 28, 8, 47, 25), 21},
new Object[]{1, LocalDateTime.of(2021, 4, 29, 13, 28, 30), 58},
new Object[]{5, LocalDateTime.of(2021, 4, 28, 16, 39, 59), 40},
new Object[]{6, LocalDateTime.of(2021, 4, 29, 23, 39, 28), 58}
);
System.out.println(max_transactions(transactions));
}
}
These code snippets implement the same algorithm in different programming languages. It first processes the transactions by day, then finds the maximum amount transactions for each day, and finally combines and sorts the resulting transactions.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorA person thinks of a number between 1 and 1000. You may ask any number questions to them, provided that the question can be answered with either "yes" or "no".
What is the minimum number of questions you needed to ask so that you are guaranteed to know the number that the person is thinking?
Recommended Readings
LeetCode Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way we
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!