从子表中选择汇总

时间:2018-08-10 17:22:27

标签: mysql sql

我有这三个表:

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中属于特定用户的所有行,以及子表amountpayments列的总和,但仅用于支付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的付款)。

有人可以建议一种更好的方式编写此查询吗?

2 个答案:

答案 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。现在我也收到了没有有效付款的帐户。

相关问题