复杂的MySQL查询,联合,交叉或自然连接?

时间:2011-09-06 09:25:05

标签: php mysql database

对于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等,我可以得到一个看起来像这样的结果,它会重复Salary表中的每一行:

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实现这一点吗?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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中。当我说“手工”时,我的意思是写一个为你做这个的程序。我们都是程序员,不是吗?

答案 2 :(得分:0)

正如Martin评论的那样,你在寻找什么在SQL Server中被称为PIVOT。 AFAIK MySQL不支持它。如果您事先知道您感兴趣的年份范围,那么您应该能够使用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)
...