塞纳里奥: 我正在使用两个表,(下面的结构)
expenses_tb person_expenses_tb
+----+-----------+ +----+------+-------------+-----------+--------+
| id | expenses | | id | year | expenses_id | person | amount |
+----+-----------+ +----+------+-------------+-----------+--------+
| 1 | Bus | | 1 | 2007 | 1 | Will | 20 |
| 2 | Food | | 2 | 2007 | 2 | Will | 200 |
| 3 | Clothes | | 3 | 2007 | 4 | Will | 1000 |
| 4 | Girlfriend| | 4 | 2007 | 5 | Will | 20 |
| 5 | Taxi | | 5 | 2008 | 3 | Will | 500 |
+----+-----------+ | 6 | 2008 | 5 | Will | 100 |
| 7 | 2008 | 2 | Holly | 200 |
| 8 | 2007 | 5 | Holly | 850 |
| .. | 2013 | ... | .... | ... |
我尝试了两种不同的查询。
SELECT person, expenses,
CASE expense_id WHEN 1 THEN amount END AS 'bus',
CASE expense_id WHEN 2 THEN amount END AS 'food',
CASE expense_id WHEN 3 THEN amount END AS 'clothes',
CASE expense_id WHEN 4 THEN amount END AS girlfriend',
CASE expense_id WHEN 5 THEN amount END AS 'taxi'
FROM person_expenses_tb p
JOIN expenses e ON e.id=p.expenses_id
WHERE p.year = 2008
GROUP BY p.person
上面的查询运行速度很快,但不会产生所需的输出。
我试过的第二个查询是
SELECT person, expenses,
(SELECT amount FROM person_expenses_tb p_bus WHERE expense_id = 1 AND p_bus.person = p.person AND year=2008) AS 'bus',
(SELECT amount FROM person_expenses_tb p_bus WHERE expense_id = 2 AND p_bus.person = p.person AND year=2008) AS 'food',
(SELECT amount FROM person_expenses_tb p_bus WHERE expense_id = 3 AND p_bus.person = p.person AND year=2008) AS 'clothes',
(SELECT amount FROM person_expenses_tb p_bus WHERE expense_id = 4 AND p_bus.person = p.person AND year=2008) AS girlfriend',
(SELECT amount FROM person_expenses_tb p_bus WHERE expense_id = 5 AND p_bus.person = p.person AND year=2008) AS 'taxi'
FROM person_expenses_tb p
JOIN expenses e ON e.id=p.expenses_id
WHERE p.year = 2008
GROUP BY p.person
这个查询产生了正确的结果,但是当[person_expenses_tb]有超过2000条记录时它非常慢。
2007年的理想结果:我将请求的年份传递给查询。
+--------+------+-----+------+---------+------------+------+
| person | Year | Bus | Food | Clothes | Girlfriend | Taxi |
+--------+------+-----+------+---------+------------+------+
| Will | 2007 | 20 | 20 | 0 | 1000 | 20 |
| Holly | 2007 | 0 | 0 | 0 | 0 | 850 |
| ... | ... | ... | ... | ... | ... | ... |
我很乐意帮助改进查询,使其运行得更快,如果有其他方法可以获得所需的输出,我将非常感谢帮助。
谢谢。
答案 0 :(得分:0)
第一个查询是正确的方法(一般而言)。您只需要聚合函数:
SELECT person,
sum(CASE p.expenses_id WHEN 1 THEN amount END) AS bus,
sum(CASE p.expenses_id WHEN 2 THEN amount END) AS food,
sum(CASE p.expenses_id WHEN 3 THEN amount END) AS clothes,
sum(CASE p.expenses_id WHEN 4 THEN amount END) AS girlfriend,
sum(CASE p.expenses_id WHEN 5 THEN amount END) AS taxi
FROM person_expenses_tb p
WHERE p.year = 2008
GROUP BY p.person;
由于MySQL的“功能”,您的版本无效。 p.expenses_id
不在group by
条款中。在这种情况下,MySQL选择一个任意值。因此,只会填充其中一列。聚合函数解决了这个问题。
因为您使用expense_id
进行透视,所以不需要连接到参考表。我还从列的名称中删除了单引号。虽然MySQL允许这样做,但这是不好的做法。只需使用单引号作为字符串常量。如果您需要转义名称,请使用引号或双引号。
(我还将expense_id
更改为expenses_id
以匹配示例数据中的命名。)