Mysql删除左边的重复项使用id连接3个表

时间:2014-01-16 08:36:16

标签: php mysql sql database

我有以下表格

hobbies
+----+-------------+---------------+
| id | employeeid  | hobby_name    |
+----+-------------+---------------+
|  1 |         123 | cooking       | 
|  2 |         123 | painting      | 
|  3 |         124 | dancing       | 
+----+-------------+---------------+

nonacad_recog
+----+-------------+---------------+
| id | employeeid  | recog_name    |
+----+-------------+---------------+
|  1 |         123 | Award1        | 
|  2 |         123 | Award2        | 
|  3 |         124 | Award3        | 
+----+-------------+---------------+

org_membership

+----+-------------+---------------+
| id | employeeid  | recog_name    |
+----+-------------+---------------+
|  1 |         123 | Boyscout      | 
|  2 |         124 | Girlscout     | 
+----+-------------+---------------+

这是我使用的查询:

SELECT h.hobby_name,r.recog_name,o.org_name
FROM hobbies as h 
JOIN nonacad_recog as r ON (h.employeeid=r.employeeid)
JOIN org_membership as o ON (r.employeeid=o.employeeid)
WHERE h.employeeid='123'

我收到了重复的输出:

+----+-------------+---------------------+
| hobby_name | recog_name  | org_name    |
+----+-------------+---------------------+
|  cooking |         Award1 | Boyscout   | 
|  cooking |         Award2 | Boyscout   | 
|  painting|         Award1 | Boyscout   | 
|  painting|         Award2 | Boyscout   | 
+----+-------------+---------------------+

我想要的输出是这样的:没有重复

+----+-------------+---------------------+
| hobby_name | recog_name  | org_name    |
+----+-------------+---------------------+
|  cooking |         Award1 | Boyscout   |
|  painting|         Award2 | NULL       | 
+----+-------------+---------------------+
如果没有要返回的内容,

还会向其他列/行提供null。 我可能错过了一些东西。

这可以实现使用mysql查询吗? 任何解决方案?

如果我得到了正确的表格,对我来说很容易 mysqli_fetch将结果关联起来并使用PHP将其显示在表上。

2 个答案:

答案 0 :(得分:2)

问题在于,在所需的输出中,您希望通过不存在的列(行号)来关联表中的行。

你可以在技术上这样做

SELECT MAX(CASE WHEN source = 1 THEN name END) hobby_name,
       MAX(CASE WHEN source = 2 THEN name END) recog_name,
       MAX(CASE WHEN source = 3 THEN name END) org_name
  FROM
(
  SELECT 1 source, id, hobby_name name, @n1 := @n1 + 1 rnum
    FROM hobbies CROSS JOIN (SELECT @n1 := 0) i
   WHERE employeeid = 123
  UNION ALL
  SELECT 2 source, id, recog_name, @n2 := @n2 + 1 rnum
    FROM nonacad_recog CROSS JOIN (SELECT @n2 := 0) i
   WHERE employeeid = 123
  UNION ALL
  SELECT 3 source, id, org_name, @n3 := @n3 + 1 rnum
    FROM org_membership CROSS JOIN (SELECT @n3 := 0) i
   WHERE employeeid = 123
   ORDER BY source, id
) q
 GROUP BY rnum

输出:

| HOBBY_NAME | RECOG_NAME | ORG_NAME |
|------------|------------|----------|
|    cooking |     Award1 | Boyscout |
|   painting |     Award2 |   (null) |

这是 SQLFiddle 演示


这是另一种解决方案。您使用GROUP_CONCAT()

将所有值打包为分隔字符串
SELECT GROUP_CONCAT(DISTINCT hobby_name ORDER BY h.id) hobby_name,
       GROUP_CONCAT(DISTINCT recog_name ORDER BY r.id) recog_name,
       GROUP_CONCAT(DISTINCT org_name ORDER BY o.id) org_name
  FROM
(
  SELECT 123 employeeid
) e LEFT JOIN hobbies h
    ON e.employeeid = h.employeeid 
    LEFT JOIN nonacad_recog r
    ON e.employeeid = r.employeeid 
    LEFT JOIN org_membership o
    ON e.employeeid = o.employeeid;

输出:

|       HOBBY_NAME |    RECOG_NAME | ORG_NAME |
|------------------|---------------|----------|
| cooking,painting | Award1,Award2 | Boyscout |

这是 SQLFiddle 演示

然后在您的客户端php代码轻松explode()列值,同时迭代结果集并构建您的演示文稿。

答案 1 :(得分:1)

我认为“限制”可以起作用:
SELECT h.hobby_name,r.recog_name,o.org_name
从业余爱好为h, nonacad_recog为r, org_membership as o
在哪里h.employeeid ='123'
AND r.employeeid = o.employeeid
AND h.employeeid = r.employeeid
限制1