基于Mysql Case Statement将一个表连接到另一个表

时间:2015-12-24 00:22:57

标签: mysql stored-procedures mysqli

我有一个名为PublicForum的表,有4个不同的用户可以发布到此表,在此表中我有2个名为AuthorId(int)AuthorType(Enum)的字段,用于显示用户ID和用户编写的用户ID交。

现在我想从PublicForum中选择全部根据AuthorType加入4个表中的1个。

我尝试使用下面的代码使用Case语句执行此操作,但其他3个表返回NULL值,我只想要与AuthorType匹配的表。

SELECT PublicForum.*, (SELECT COUNT(*) FROM PublicForumComment WHERE PublicForumComment.ForumId = PublicForum.ForumId) AS CommentCount, 
Student.*, Parent.*, Teacher.*, Counsellor.* FROM PublicForum 
LEFT JOIN Student ON (CASE WHEN PublicForum.AuthorType='Student' AND PublicForum.AuthorId = Student.StudentId THEN 1 ELSE 0 END = 1) 
LEFT JOIN Parent ON (CASE WHEN PublicForum.AuthorType='Parent' AND PublicForum.AuthorId = Parent.ParentId THEN 1 ELSE 0 END = 1) 
LEFT JOIN Teacher ON (CASE WHEN PublicForum.AuthorType='Teacher' AND PublicForum.AuthorId = Teacher.TeacherId THEN 1 ELSE 0 END = 1) 
LEFT JOIN Counsellor ON (CASE WHEN PublicForum.AuthorType='Counsellor' AND PublicForum.AuthorId = Counsellor.CounsellorId THEN 1 ELSE 0 END = 1) 
ORDER BY PublicForum.ForumId DESC LIMIT 10

还有其他方法可以实现这个目标吗?

2 个答案:

答案 0 :(得分:1)

您无法有条件地加入。执行此操作的方法是使用UNION组合的单独查询。

SELECT t1.*, COUNT(pfc.ForumId) AS pfc_count
FROM (
    SELECT p.*, s.StudentName AS Name, s.StudentCol2 AS Col2, s.StudentCol3 AS Col3, s.StudentCol4 AS Col4
    FROM PublicForum AS p
    JOIN Student AS s ON p.AuthorId = s.StudentId
    WHERE p.AuthorType = 'Student'
    UNION
    SELECT p.*, pa.*
    FROM PublicForum AS p
    JOIN Parent AS pa ON p.AuthorId = pa.ParentId
    WHERE p.AuthorType = 'Parent'
    UNION
    SELECT p.*, t.*
    FROM PublicForum AS p
    JOIN Teacher AS t ON p.AuthorId = t.TeacherId
    WHERE p.AuthorType = 'Teacher'
    UNION
    SELECT p.*, c.*
    FROM PublicForum AS p
    JOIN Counsellor AS c ON p.AuthorId = c.CounsellorId
    WHERE p.AuthorType = 'Counsellor') AS t1
LEFT JOIN PublicForumComments AS pfc ON t1.ForumId = pfc.ForumId
GROUP BY t1.ForumId
ORDER BY t1.ForumId DESC
LIMIT 10

对所有连接表使用tablename.*取决于它们具有相同数量的列,并且所有列都是类似的并且顺序相同。然后,第一个子查询中的AS子句为来自UNION的列提供通用名称。

答案 1 :(得分:1)

也许这个?您可能需要对列进行命名并将其完整起来..

Select * from (
SELECT PublicForum.*,
 (SELECT COUNT(*) FROM PublicForumComment WHERE PublicForumComment.ForumId = PublicForum.ForumId) AS CommentCount, 
Student.* 
FROM PublicForum 
JOIN Student ON (CASE WHEN PublicForum.AuthorType='Student' AND PublicForum.AuthorId = Student.StudentId THEN 1 ELSE 0 END = 1) 
UNION 
SELECT PublicForum.*,
 (SELECT COUNT(*) FROM PublicForumComment WHERE PublicForumComment.ForumId = PublicForum.ForumId) AS CommentCount, 
Parent.*
FROM PublicForum 
JOIN Parent ON (CASE WHEN PublicForum.AuthorType='Parent' AND PublicForum.AuthorId = Parent.ParentId THEN 1 ELSE 0 END = 1) 
UNION
SELECT PublicForum.*,
 (SELECT COUNT(*) FROM PublicForumComment WHERE PublicForumComment.ForumId = PublicForum.ForumId) AS CommentCount, 
Teacher.*
FROM PublicForum 
JOIN Teacher ON (CASE WHEN PublicForum.AuthorType='Teacher' AND PublicForum.AuthorId = Teacher.TeacherId THEN 1 ELSE 0 END = 1) 
UNION
SELECT PublicForum.*,
 (SELECT COUNT(*) FROM PublicForumComment WHERE PublicForumComment.ForumId = PublicForum.ForumId) AS CommentCount, 
Counsellor.*
FROM PublicForum 
JOIN Counsellor ON (CASE WHEN PublicForum.AuthorType='Teacher' AND PublicForum.AuthorId = Teacher.TeacherId THEN 1 ELSE 0 END = 1) 
) as tmp1
ORDER BY ForumId DESC LIMIT 10