0

我正在处理一个目前运行良好的查询(我正在使用来自前端的输入来生成 WHERE 子句),但我希望能够搜索另一个参数,这真的让我难以置信。

  1. groups包含 id、name。
  2. persons是我要检索的人的表。
  3. group_memberships是我的组<->人多对多关系表。列是参与者 (person.id) 和组 (groups.id)

检索到的结果集的最后一列是 group_memberships 的串联,但其中“1、2、3”已通过 JOIN 替换为组的真实姓名。

今天的查询如下:

SELECT
  `persons`.`id`,
  CONCAT_WS(\' \', `fname`, `lname`) AS `full_name`,
  `job_title`,
  `email`,
  `phone`,
  `participant_group_memberships`.`memberships`
FROM
  `persons`
  LEFT JOIN (SELECT
               `participant`, `name`,
               GROUP_CONCAT(`groups`.`name` ORDER BY `groups`.`name`
                            SEPARATOR  \', \') AS `memberships`
             FROM
               `group_memberships` JOIN `groups`
                ON (`groups`.`id` = `group_memberships`.`group`)
             GROUP BY `participant`) AS `participant_group_memberships`
  ON (`participant_group_memberships`.`participant` = `persons`.`id`)
WHERE TRUE . $where . '
ORDER BY `full_name`

如果我添加 WHERE name = 'search_query_group' 那么串联列表只会显示我不想要的组。我仍然想显示该人所属的所有组。

我还想通过 1 个查询来实现这一点,并尽可能避免使用 IN()。

在此处输入图像描述

如您所见,最后一列(使用 GROUP_CONCAT 生成)将仅显示我搜索的组,而不是该人所属的所有组。

4

1 回答 1

1

您可以在子查询的 HAVING 子句中使用 SUM 和 CASE 语句来包含搜索结果。您还需要将子查询的联接更改为 INNER JOIN。这将返回某个组中的所有人员,并显示他们所属的所有组。

SELECT  `persons`.`id`,
        CONCAT_WS(\' \', `fname`, `lname`) AS `full_name`,
        `job_title`,
        `email`,
        `phone`,
        `participant_group_memberships`.`memberships`

FROM    `persons` 

        JOIN `pers_department`
        ON (`pers_department`.`pers_rid` = `persons`.`id`)

        JOIN 
        (SELECT `participant`, `name`,
                GROUP_CONCAT(`groups`.`name` ORDER BY `groups`.`name`
                            SEPARATOR  \', \') AS `memberships`
         FROM   `group_memberships` 
                JOIN `groups` ON (`groups`.`id` = `group_memberships`.`group`)
         GROUP BY `participant`
         HAVING SUM(CASE WHEN name = 'search_query_group' THEN 1 ELSE 0 END) > 0
        ) AS `participant_group_memberships`
        ON (`participant_group_memberships`.`participant` = `persons`.`id`)

WHERE TRUE . $where . '

ORDER BY `full_name`
于 2013-02-20T15:21:12.277 回答