PostgreSQL 连接子查询不能限制查询
PostgreSQL join subquery can't restrict query
将此问题移至 DBA STACKEXCHANGE:
https://dba.stackexchange.com/questions/137878/postgresql-join-subquery-cant-restrict-query
我正在做一个支票拆分项目,该项目拆分 activity 的欠款。用户可以属于多个 'groups',每个用户都有自己的 运行ning 余额。
我正在尝试 运行 一个查询,该查询将 return 个人用户 'amount owed' 跨所有组。
目前查询如下所示:
SELECT
SUM(owe)
FROM (
SELECT
(expenses.amount/count(*))
AS owe
FROM expenses
LEFT JOIN user_expenses
ON (
expenses.id = user_expenses.expense_id
)
WHERE expenses.paid_by != 1
GROUP BY expenses.id
)
AS total;
问题是此查询全面检索所有费用。我想做的是通过使用限制:
WHERE user_expenses.user_id = 1
如何将其添加到上述查询(在子查询中)以将结果限制为仅与该用户关联的费用?
TABLE 架构(如果有帮助的话):
USERS
id
name
username
email
EXPENSES
id
created_at
updated_at
title
amount
group_id
paid_by
img_url
note
USER_EXPENSES (join table)
id
expense_id
user_id
GROUPS
id
created_at
name
desc
USER_GROUPS
id
user_id
group_id
更多示例信息以供说明:
如果我 运行 这个查询 -
SELECT
e.title,
e.amount,
(e.amount/count(*)) AS owe, count(*) AS members
FROM expenses e LEFT JOIN
user_expenses ue
ON e.id = ue.expense_id
WHERE e.paid_by != 1
GROUP BY e.id;
我得到这样的结果(带有虚拟数据):
如果我运行以下:
SELECT
e.title,
e.amount,
(e.amount/count(*)) AS owe, count(*) AS members
FROM expenses e LEFT JOIN
user_expenses ue
ON e.id = ue.expense_id AND ue.user_id = 1
WHERE e.paid_by != 1
GROUP BY e.id;
我明白了(注意成员数):
如果您的查询有效,那么您只需将其添加到子查询中:
SELECT SUM(owe)
FROM (SELECT (e.amount/count(*)) AS owe
FROM expenses e LEFT JOIN
user_expenses ue
ON e.id = ue.expense_id AND ue.user_id = 1
WHERE expenses.paid_by <> 1
GROUP BY expenses.id
) t;
我们最终得出了两个解决方案。非常感谢一位了不起的团队成员,他通过它提供了强大的支持,并做出了一些有用的东西,而且可以认为它更便宜一些。尽管如此,还是要感谢他们。
事实证明,HAVING 是获得所需解决方案的关键部分(感谢@andriy-m):
HAVING clause was added to SQL because the WHERE keyword could not be used with aggregate functions
SELECT SUM(owe)
FROM (
SELECT
(e.amount/count(*)) AS owe
FROM expenses e
LEFT JOIN
user_expenses ue
ON e.id = ue.expense_id
WHERE e.paid_by != 1
GROUP BY e.id
HAVING COUNT(ue.user_id = 1 OR NULL) > 0
)
AS total;
另外,向为此付出努力的 PJ 表示敬意:
SELECT SUM(owe)
FROM (SELECT (expenses.amount/count(*)) AS owe
FROM expenses
LEFT JOIN user_expenses ON (expenses.id = user_expenses.expense_id)
WHERE expenses.paid_by != 1
AND expense_id IN (select expense_id from users LEFT JOIN user_expenses
ON (1 = user_expenses.user_id)) GROUP BY expenses.id)
AS total;
将此问题移至 DBA STACKEXCHANGE: https://dba.stackexchange.com/questions/137878/postgresql-join-subquery-cant-restrict-query
我正在做一个支票拆分项目,该项目拆分 activity 的欠款。用户可以属于多个 'groups',每个用户都有自己的 运行ning 余额。
我正在尝试 运行 一个查询,该查询将 return 个人用户 'amount owed' 跨所有组。
目前查询如下所示:
SELECT
SUM(owe)
FROM (
SELECT
(expenses.amount/count(*))
AS owe
FROM expenses
LEFT JOIN user_expenses
ON (
expenses.id = user_expenses.expense_id
)
WHERE expenses.paid_by != 1
GROUP BY expenses.id
)
AS total;
问题是此查询全面检索所有费用。我想做的是通过使用限制:
WHERE user_expenses.user_id = 1
如何将其添加到上述查询(在子查询中)以将结果限制为仅与该用户关联的费用?
TABLE 架构(如果有帮助的话):
USERS
id
name
username
email
EXPENSES
id
created_at
updated_at
title
amount
group_id
paid_by
img_url
note
USER_EXPENSES (join table)
id
expense_id
user_id
GROUPS
id
created_at
name
desc
USER_GROUPS
id
user_id
group_id
更多示例信息以供说明: 如果我 运行 这个查询 -
SELECT
e.title,
e.amount,
(e.amount/count(*)) AS owe, count(*) AS members
FROM expenses e LEFT JOIN
user_expenses ue
ON e.id = ue.expense_id
WHERE e.paid_by != 1
GROUP BY e.id;
我得到这样的结果(带有虚拟数据):
如果我运行以下:
SELECT
e.title,
e.amount,
(e.amount/count(*)) AS owe, count(*) AS members
FROM expenses e LEFT JOIN
user_expenses ue
ON e.id = ue.expense_id AND ue.user_id = 1
WHERE e.paid_by != 1
GROUP BY e.id;
我明白了(注意成员数):
如果您的查询有效,那么您只需将其添加到子查询中:
SELECT SUM(owe)
FROM (SELECT (e.amount/count(*)) AS owe
FROM expenses e LEFT JOIN
user_expenses ue
ON e.id = ue.expense_id AND ue.user_id = 1
WHERE expenses.paid_by <> 1
GROUP BY expenses.id
) t;
我们最终得出了两个解决方案。非常感谢一位了不起的团队成员,他通过它提供了强大的支持,并做出了一些有用的东西,而且可以认为它更便宜一些。尽管如此,还是要感谢他们。
事实证明,HAVING 是获得所需解决方案的关键部分(感谢@andriy-m):
HAVING clause was added to SQL because the WHERE keyword could not be used with aggregate functions
SELECT SUM(owe)
FROM (
SELECT
(e.amount/count(*)) AS owe
FROM expenses e
LEFT JOIN
user_expenses ue
ON e.id = ue.expense_id
WHERE e.paid_by != 1
GROUP BY e.id
HAVING COUNT(ue.user_id = 1 OR NULL) > 0
)
AS total;
另外,向为此付出努力的 PJ 表示敬意:
SELECT SUM(owe)
FROM (SELECT (expenses.amount/count(*)) AS owe
FROM expenses
LEFT JOIN user_expenses ON (expenses.id = user_expenses.expense_id)
WHERE expenses.paid_by != 1
AND expense_id IN (select expense_id from users LEFT JOIN user_expenses
ON (1 = user_expenses.user_id)) GROUP BY expenses.id)
AS total;