我好几天都遇到了以下问题。我有点设法解决它,但性能是困扰我的。
基本上我有一个人员表,两个表(debt
和wealth
),引用person
。 debt
/ wealth
个表可以有多行引用相同的personID
。
我需要一个结果,我只需将所有列出的债务和财富总和列为自己的列。
首先让我代表我的表格:
表'人':
| ID | name |
|----|---------|
| 1 | Adam |
| 2 | Berg |
| 3 | Carl |
| 4 | David |
表'财富':
| ID | personID | value |
|----|----------|----------|
| 1 | 1 | 100 |
| 2 | 1 | 2000 |
| 3 | 2 | 30000 |
| 4 | 3 | 400000 |
| 5 | 3 | 5000000 |
表'债务':
| ID | personID | value |
|----|----------|----------|
| 1 | 1 | 100 |
| 2 | 1 | 2000 |
| 3 | 2 | 30000 |
| 4 | 2 | 400000 |
| 5 | 3 | 5000000 |
预期结果:
| personID | debtSum | wealthSum |
|----------|---------|-----------|
| 1 | 2100 | 2100 |
| 2 | 30000 | 430000 |
| 3 | 5400000 | 5000000 |
| 4 | (null) | (null) |
我的解决方案:
SELECT SQL_NO_CACHE p.ID, debtSum, wealthSum
FROM person AS p
LEFT JOIN (SELECT personID, SUM(value) AS debtSum FROM debt GROUP BY personID) AS d ON d.personID = p.ID
LEFT JOIN (SELECT personID, SUM(value) AS wealthSum FROM wealth GROUP BY personID) AS w ON w.personID = p.ID
此查询返回正确的数据,但正如我所说,性能让我担心。例如,如果我在债务表中为不存在的人添加了数千行(例如,使用personID = 5),则执行查询需要更长的时间。我想它确实总结了那个人的所有数据,虽然结果不需要它?
我正在使用SQL Server 2008,虽然 SQL Fiddle 正在使用MySQL(如果这有所不同)。
我很欣赏有关如何提高查询性能的提示。我的想法已经不多了。
答案 0 :(得分:1)
嗯,这就是我将如何做到这一点,虽然我下注正确的索引会对性能产生比查询结构更大的影响:
编辑帖子评论:
SELECT ID, SUM(debtSum) AS debtSum, SUM(wealthSum) AS wealthSum
FROM (
SELECT p.ID, d.value AS debtSum, NULL AS wealthSum
FROM person AS p
LEFT JOIN debt d ON d.personID = p.ID
UNION ALL
SELECT p.ID, NULL AS debtSum, w.Value AS wealthSum
FROM person AS p
LEFT JOIN wealth w ON w.personID = p.ID
) t
GROUP BY t.ID
您应该在Person.Id,Debt.PersonID和Wealth.PersonID上有索引