具有连接操作的 MySQL group_concat() 函数

标签 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() 逗号分隔。我该如何修复这个查询?

最佳答案

如果我理解您的要求,您希望在一所学校拥有所需建筑和教职工时收回所有建筑和教职工。

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

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

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 ;

关于具有连接操作的 MySQL group_concat() 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30997301/

相关文章:

php - 是否可能返回类似 Excel 的查询?

mysql - MySQL 中的 Rank 函数分配一个等级

php - 在本月 8 日和上个月 8 日之间选择,每个月

python - 在 Windows 10 中为 python 安装 mysqlclient 时出错

sql复杂的类似表达式@user

mysql - 带奖金的薪资选择 mysql

mysql - WHERE 子句获取(可能)跨越新一天的事件

mysql - 获取每个列值的前 N ​​个结果

mysql 匹配多个and 和or

mysql - rails : Order found objects with a has_and_belongs_to_many relationship