我有这三个表:
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
中属于特定用户的所有行,以及子表amount
中payments
列的总和,但仅用于支付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的付款)。
有人可以建议一种更好的方式编写此查询吗?
答案 0 :(得分:0)
使用join和where子句进行过滤
select u.user_id ,p.account_id ,sum(p.amount) as totalAmount
from payments p inner join accounts a
on a.account_id=p.account_id
inner join users u on a.user_id=u.user_id
where p.extra_charge =0
group by u.user_id ,p.account_id
答案 1 :(得分:0)
我明白了
代替
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;
我用过
SELECT
a.account_id,
COALESCE(SUM(p.amount), 0) total_amount
FROM
accounts a
LEFT JOIN
payments p ON p.account_id = a.account_id AND p.extra_charge = 0
WHERE
a.user_id = ?
GROUP BY
a.account_id;
我扩大了WHERE子句,但限制了JOIN。现在我也收到了没有有效付款的帐户。