Your question is Analyze and Optimize a SQL Query. Take a moment with it on the right.
Talk me through your thinking if you like. When you're confident, submit your answer and I'll grade it like a real screen (7/10 or better passes).
WEX issues fleet fuel cards that companies give their drivers. An engineer is reviewing the query below, which totals each card's fuel spend for the last 30 days and reports the merchant category of its most recent purchase, for a fraud-monitoring dashboard. It's flagged as one of the slowest queries hitting the fuel_transactions table.
CREATE TABLE fleet_cards (
card_id BIGINT PRIMARY KEY,
company_id BIGINT,
driver_name TEXT
);
CREATE TABLE merchants (
merchant_id INT PRIMARY KEY,
merchant_name TEXT,
category TEXT -- 'fuel', 'maintenance', 'toll', 'other'
);
CREATE TABLE fuel_transactions (
transaction_id BIGINT PRIMARY KEY,
card_id BIGINT REFERENCES fleet_cards(card_id),
merchant_id INT REFERENCES merchants(merchant_id),
amount NUMERIC(10,2),
txn_time TIMESTAMP
);
CREATE INDEX idx_fuel_txn_time ON fuel_transactions(txn_time);
SELECT
fc.card_id,
fc.driver_name,
SUM(ft.amount) AS total_spend,
(SELECT m.category FROM merchants m
JOIN fuel_transactions ft2 ON ft2.merchant_id = m.merchant_id
WHERE ft2.card_id = fc.card_id
ORDER BY ft2.txn_time DESC LIMIT 1) AS last_category
FROM fleet_cards fc
JOIN fuel_transactions ft ON ft.card_id = fc.card_id
WHERE CAST(ft.txn_time AS DATE) >= CURRENT_DATE - 30
GROUP BY fc.card_id, fc.driver_name
HAVING SUM(ft.amount) > 500 OR COUNT(ft.transaction_id) > 40
ORDER BY total_spend DESC;
How would you analyze this given query and optimize it?