为什么在查看每个账户的当前余额时要使用 max(balance)? SQL 面试问题
Why should max(balance) be used when looking at current balance for each account? SQL interview question
有人问我这个问题
'Why do you need to use the max function on the balance column to get the current balance for each account?'
对于以下查询示例:
SELECT
universe -- (bookmaker name)
,wallet_id
,sum(operator_balance_delta) as profit
,max(balance) as current_balance
FROM
transactions
INNER JOIN
(
SELECT
id
,universe
,balance
FROM
wallets -- (accounts table)
WHERE
created_at BETWEEN '2021-01-01 00:00:00' AND '2021-02-01 00:00:00'
AND currency = 'GBP'
AND last_bet_at IS NOT NULL
AND balance >= 0
LIMIT 100
) AS accounts ON accounts.id = transactions.wallet_id
WHERE type_id IN (SELECT id FROM transaction_types WHERE code IN ('bet','casino-wager','virtualsports-wager','live-casino-wager','bingo-wager'))
GROUP BY wallet_id,type_id,universe
据我所知,maximum 顾名思义就是给出帐户的最大余额,不一定是当前余额。我认为唯一可能的情况是,最大值是否以某种方式考虑了日期,因此返回最大值(日期)的余额,或者换句话说,当前余额。
如有任何帮助,我们将不胜感激!
您需要在此处使用聚合,因为 balance
列不是 GROUP BY
的一部分。 任何不在 GROUP BY
中的列必须有聚合。
max(balance)
不会 给你账户的最大余额,因为 balance
列来自 wallet
table,而不是 transaction
table。由于 wallet_id
是 GROUP BY
的一部分,并且 balance
在功能上依赖于它,因此只有一个 balance
值。
这里真正应该发生的是 balance
应该在 GROUP BY
。 或者,transaction
table应该在子查询中预先分组。
此查询的其他问题如下所示:
应使用 - Table 别名,列应引用 table 它们来自
created_at BETWEEN ...
可能是错误的,因为它包括终点。它应该使用半开区间 created_at >= ... AND created_at < ...
- 子查询
type_id IN (SELECT ...
不是必需的,可以是一个普通的连接,因为 id
是一个主键
LIMIT
没有 ORDER BY
会给出不确定的结果
所以最终的查询应该是这样的,如果我写的话:
SELECT
w.universe -- (bookmaker name)
,w.id as wallet_id
,sum(t.operator_balance_delta) as profit
,w.balance as current_balance
FROM
transactions t
JOIN
(
SELECT
w.id
,w.universe
,w.balance
FROM
wallets w -- (accounts table)
WHERE
w.created_at >= '2021-01-01 00:00:00'
AND w.created_at < '2021-02-01 00:00:00'
AND w.currency = 'GBP'
AND w.last_bet_at IS NOT NULL
AND w.balance >= 0
ORDER BY balance DESC
LIMIT 100
) AS a ON a.id = t.wallet_id
JOIN transaction_types tt
ON tt.type_id = t.id
AND tt.code IN (
'bet',
'casino-wager',
'virtualsports-wager',
'live-casino-wager',
'bingo-wager')
GROUP BY
w.id,
w.universe,
w.balance,
t.type_id;
有人问我这个问题 'Why do you need to use the max function on the balance column to get the current balance for each account?' 对于以下查询示例:
SELECT
universe -- (bookmaker name)
,wallet_id
,sum(operator_balance_delta) as profit
,max(balance) as current_balance
FROM
transactions
INNER JOIN
(
SELECT
id
,universe
,balance
FROM
wallets -- (accounts table)
WHERE
created_at BETWEEN '2021-01-01 00:00:00' AND '2021-02-01 00:00:00'
AND currency = 'GBP'
AND last_bet_at IS NOT NULL
AND balance >= 0
LIMIT 100
) AS accounts ON accounts.id = transactions.wallet_id
WHERE type_id IN (SELECT id FROM transaction_types WHERE code IN ('bet','casino-wager','virtualsports-wager','live-casino-wager','bingo-wager'))
GROUP BY wallet_id,type_id,universe
据我所知,maximum 顾名思义就是给出帐户的最大余额,不一定是当前余额。我认为唯一可能的情况是,最大值是否以某种方式考虑了日期,因此返回最大值(日期)的余额,或者换句话说,当前余额。
如有任何帮助,我们将不胜感激!
您需要在此处使用聚合,因为 balance
列不是 GROUP BY
的一部分。 任何不在 GROUP BY
中的列必须有聚合。
max(balance)
不会 给你账户的最大余额,因为 balance
列来自 wallet
table,而不是 transaction
table。由于 wallet_id
是 GROUP BY
的一部分,并且 balance
在功能上依赖于它,因此只有一个 balance
值。
这里真正应该发生的是 balance
应该在 GROUP BY
。 或者,transaction
table应该在子查询中预先分组。
此查询的其他问题如下所示:
-
应使用
- Table 别名,列应引用 table 它们来自
created_at BETWEEN ...
可能是错误的,因为它包括终点。它应该使用半开区间created_at >= ... AND created_at < ...
- 子查询
type_id IN (SELECT ...
不是必需的,可以是一个普通的连接,因为id
是一个主键 LIMIT
没有ORDER BY
会给出不确定的结果
所以最终的查询应该是这样的,如果我写的话:
SELECT
w.universe -- (bookmaker name)
,w.id as wallet_id
,sum(t.operator_balance_delta) as profit
,w.balance as current_balance
FROM
transactions t
JOIN
(
SELECT
w.id
,w.universe
,w.balance
FROM
wallets w -- (accounts table)
WHERE
w.created_at >= '2021-01-01 00:00:00'
AND w.created_at < '2021-02-01 00:00:00'
AND w.currency = 'GBP'
AND w.last_bet_at IS NOT NULL
AND w.balance >= 0
ORDER BY balance DESC
LIMIT 100
) AS a ON a.id = t.wallet_id
JOIN transaction_types tt
ON tt.type_id = t.id
AND tt.code IN (
'bet',
'casino-wager',
'virtualsports-wager',
'live-casino-wager',
'bingo-wager')
GROUP BY
w.id,
w.universe,
w.balance,
t.type_id;