MySQL group_concat()函数具有join操作

时间:2015-06-23 08:13:04

标签: mysql

我有以下表格:

CREATE TABLE school(
    schoolId VARCHAR(36),
    sname VARCHAR(64)
    PRIMARY KEY(schoolId)
);

CREATE TABLE school_building(
    schoolId VARCHAR(36),
    bname VARCHAR(64),
    PRIMARY KEY(schoolId, bname),
    FOREIGN KEY (schoolId) REFERENCES school(schoolId)
);

CREATE TABLE school_faculty(
    schoolId VARCHAR(36),
    fname VARCHAR(64),
    PRIMARY KEY(schoolId, fname),
    FOREIGN KEY (schoolId) REFERENCES school(schoolId)
);

我想写一个查询来检索学校及其建筑物和院系,以逗号分隔的字段。当我只写下面的内容时:

SELECT school.*, group_concat(bname SEPARATOR ',') as buildings, group_concat(fname SEPARATOR ',') as faculties 
FROM school S 
LEFT OUTER JOIN school_building B 
on S.schoolId = B.schoolId 
LEFT OUTER JOIN school_faculty F 
on S.schoolId = F.schoolId 
GROUP BY school.schoolId;

它完全按照我的要求给出了结果。但是,如果建筑物名称或教员名称符合某些条件,我想写一个查询来选择学校及其建筑物和学校院系作为逗号分隔的字段。例如,我想选择学校(如果它有医学或工程学院)或(它有医院或餐厅)建筑。为此,我写下以下内容:

SELECT school.*, group_concat(bname SEPARATOR ',') as buildings, group_concat(fname SEPARATOR ',') as faculties 
FROM school S 
LEFT OUTER JOIN school_building B 
on S.schoolId = B.schoolId 
LEFT OUTER JOIN school_faculty F 
on S.schoolId = F.schoolId 
WHERE B.name in ('hospital', 'restaurant') or F.name in ('medicine', 'engineering') 
GROUP BY school.schoolId;

然而,尽管此查询返回正确的学校,但它会错误地带来建筑物或院系。例如,假设一所学校有三栋名为医院和酒店的建筑物。但是,在结果集中,学校只有医院。显然,where子句以某种方式阻止了where子句中未列出的建筑物被group_concat()逗号分隔。如何解决此问题?

2 个答案:

答案 0 :(得分:1)

如果我了解您的要求,您希望在学校有所需要的时候带回所有建筑物和院系。

可能有两种方法可以做到这一点。您可以使用几个子查询来查找具有必要建筑或学院的学校,然后将其与主查询联系起来。

或者另一种方法是使用HADING使用FIND_IN_SET来检查字段是否包含所需的建筑物或教师。

SELECT school.*, GROUP_CONCAT(DISTINCT bname SEPARATOR ',') AS buildings, GROUP_CONCAT(DISTINCT fname SEPARATOR ',') AS faculties 
FROM school S 
LEFT OUTER JOIN school_building B 
ON S.schoolId = B.schoolId 
LEFT OUTER JOIN school_faculty F 
ON S.schoolId = F.schoolId 
GROUP BY school.schoolId 
HAVING FIND_IN_SET('hospital', buildings)
OR FIND_IN_SET('restaurant', buildings)
OR FIND_IN_SET('engineering', faculties) 
OR FIND_IN_SET('medicine', faculties) 

修改

使用piotrms建议: -

SELECT S.*, GROUP_CONCAT(DISTINCT B.bname SEPARATOR ',') AS buildings, GROUP_CONCAT(DISTINCT F.fname SEPARATOR ',') AS faculties 
FROM school S 
LEFT OUTER JOIN school_building B1 
ON S.schoolId = B1.schoolId 
AND B1.bname IN ('hospital', 'restaurant')
LEFT OUTER JOIN school_building B 
ON S.schoolId = B.schoolId 
LEFT OUTER JOIN school_faculty F1 
ON S.schoolId = F1.schoolId 
AND F1.fname IN ('engineering', 'medicine')
LEFT OUTER JOIN school_faculty F 
ON S.schoolId = F.schoolId 
WHERE B1.schoolId IS NOT NULL OR F1.schoolId IS NOT NULL
GROUP BY S.schoolId ;

答案 1 :(得分:1)

GetContactList

请参阅sqlfiddle上的示例。