3

Senario:我正在使用两个表,(结构如下)

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  |
| ...    | ...  | ... | ...  | ...     | ...        | ...  |

我很想获得有关如何改进查询以使其运行得更快的帮助,如果有另一种获得所需输出的方法,我将不胜感激。

谢谢你。

4

1 回答 1

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_idexpenses_id与您的示例数据中的命名相匹配。)

于 2013-09-03T13:43:53.477 回答