2011-09-06 123 views
1

对于MySQL查询有一个奇怪的问题,我无法真正弄清楚如何按照我希望组织数据。复杂的MySQL查询,联合,相交或自然连接?

我在PHP中构建搜索脚本,但数据库结构不是我想要的样子。

好了,说我有三个表(这些是完全由):

EMPLOYES 
id  name  city  hired 
------------------------------------------------- 
1  Jim   0810  2001 
2  Stan  6777  2002 
3  George  6532  2009 

SALARY 
id  amount  year 
-------------------------------- 
1  2000  2009 
1  2500  2010 
1  2800  2011 
2  2100  2009 
2  2200  2010 
2  2500  2011 
3  2200  2009 
3  2300  2010 
3  2800  2011 

CONTACT 
city areacode cityname 
----------------------------- 
0810 0300  Tampa 
6777 0800  Miami 
6532 0210  Atlanta 

现在,如果我坚持LEFT JOIN的等我能够得到的结果是这个样子,哪里它重复每行中的工资表:

name cityname hired salary 
---------------------------------- 
Jim  Tampa  2001 2000 
Jim  Tampa  2001 2500 
Jim  Tampa  2001 2800 
... 

但我真正想要的是这样的:

name cityname hired 2009 2010 2011 
------------------------------------------------ 
Jim  Tampa  2001 2000 2500 2800 
... 

任何我可以用SQL实现的方法?

+0

MySQL的东西并不支持'INTERSECT'我相信,但它看起来像你需要一个'PIVOT无论如何,'/'CROSS TAB'查询。 –

回答

0
SELECT EMPLOYES.*, GROUP_CONCAT(salery) 
FROM EMPLOYES JOIN SALERY USING(id) 
GROUP BY id 

http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

但你最好用手工做的,而不是在SQL。当我说“手工”时,我的意思是通过编写一个可以帮助你的程序。我们都是程序员,不是吗?

+0

我会试试看!希望有另一种方式,我唯一的数据源是来自外部来源,具有.xls格式的13000条记录。没办法,我要手动编辑=/ – Marcus

+0

不要直接用手写,写一个程序。 – sanmai

+0

哈哈,真的 - 也许应该看看它。 – Marcus

1

您需要一个PIVOT查询。因为无论如何你的桌子都是这样构成的,所以我会把这个桌子做成桌子,这样你就可以看到这个方法。

name cityname year salary 
---------------------------------- 
Jim  Tampa  2009 2000 
Jim  Tampa  2010 2500 
Jim  Tampa  2011 2800 

转动这一点,你会用

SELECT name, 
     cityname, 
     MAX(CASE WHEN year = 2009 then salary end) AS `2009`, 
     MAX(CASE WHEN year = 2010 then salary end) AS `2010`, 
     MAX(CASE WHEN year = 2011 then salary end) AS `2011`, 
FROM T 
GROUP BY name, 
     cityname 
0

正如马丁评论,什么youre寻找被称为在SQL Server PIVOT。 AFAIK MySQL不支持它。如果你知道今年的范围中的youre事先然后intrested你应该能够构建使用LEFT JOIN的查询,如

SELECT 
    E.name, 
    S2009.amount AS `2009`, 
    S2010.amount AS `2010`, 
    ... 
FROM EMPLOYES E 
LEFT JOIN SALARY S2009 ON(S2009.id = E.id)AND(S2009.year = 2009) 
LEFT JOIN SALARY S2010 ON(S2010.id = E.id)AND(S2010.year = 2010) 
...