【发布时间】:2018-08-10 17:22:27
【问题描述】:
我有这三个表:
CREATE TABLE users (
user_id INT NOT NULL PRIMARY KEY
);
CREATE TABLE accounts (
account_id INT NOT NULL PRIMARY KEY,
user_id INT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users (user_id)
);
CREATE TABLE payments (
payment_id INT NOT NULL,
account_id INT NOT NULL,
amount DECIMAL(9,2) NOT NULL,
extra_charge TINYINT(1) NOT NULL DEFAULT 0,
FOREIGN KEY (account_id) REFERENCES accounts (account_id)
);
付款属于账户,账户属于用户。
我想选择accounts 中属于特定用户的所有行,以及子表payments 中amount 列的总和,但仅适用于extra_charge 列所在的付款0.
我开始使用子查询:
SELECT
a.account_id,
COALESCE(t.total_amount, 0) total_amount
FROM
accounts a
LEFT JOIN (
SELECT
p.account_id,
SUM(p.amount) total_amount
FROM
payments p
WHERE
p.extra_charge = 0
GROUP BY
p.account_id
) p USING (account_id)
WHERE
a.user_id = ?;
但这运行缓慢,因为对整个 payments 表求和是很多不必要的工作。通过这样做,我可以避免不必要地对整个 payments 表求和:
SELECT
a.account_id,
COALESCE(t.total_amount, 0) total_amount
FROM
accounts a
LEFT JOIN (
SELECT
p.account_id,
SUM(p.amount) total_amount
FROM
payments p
LEFT JOIN
accounts a USING (account_id)
WHERE
a.user_id = ?
AND
p.extra_charge = 0
GROUP BY
p.account_id
) p USING (account_id)
WHERE
a.user_id = ?;
但提供两次user_id 似乎很麻烦。
我也尝试过只使用连接而不使用子查询来编写它:
SELECT
a.account_id
SUM(p.amount) total_amount
FROM
accounts a
LEFT JOIN
payments p USING (account_id)
WHERE
a.user_id = ?
AND
p.extra_charge = 0
GROUP BY
a.account_id;
但是我的结果是缺少任何没有付款的帐户(或者没有任何付款,extra_charge = 0)。
谁能提出一个更好的方法来编写这个查询?
【问题讨论】: