选择连接中每个*记录包含字符串的位置

时间:2018-04-27 09:49:15

标签: mysql sql

我有以下MySQL表:

n_companies:

id     company_name
1      Company A
2      Company B

n_contacts:

id     company_id     contact_name
1      1              John
2      1              Frank
3      2              Bobby
4      2              Sophie

n_custom:

id   custom_type   custom_type_id    gender   fav_colour
1    contacts      1                 male     red
2    contacts      2                 male     red
3    contacts      3                 male     red
4    contacts      4                 female   green

我正在创建一个搜索用户界面,允许用户搜索任何/每个/没有记录包含字符串的位置。

这是我觉得应该为之工作的查询:

查找公司(n_companies),其中每个联系人(n_contacts)都是男性(存储在自定义字段表n_custom中):

SELECT 
    `n_companies`.`id`,
    `n_companies`.`company_name`
FROM `n_companies`
LEFT JOIN `n_contacts`
    ON ( `n_contacts`.`company_id` = `n_companies`.`id` )
LEFT JOIN `n_custom` AS `custom_contacts`
    ON ( `n_contacts`.`id` = `custom_contacts`.`custom_type_id`
    AND `custom_contacts`.`custom_type` = 'contacts' )
WHERE  
    EXISTS (
        SELECT `id`
        FROM   `n_custom`
        WHERE  `n_custom`.`custom_type_id` = `n_contacts`.`id` AND `n_custom`.`custom_type` = 'contacts'
        AND `n_custom`.`gender` LIKE '%male%'
    )
    AND NOT EXISTS (
        SELECT `id`
        FROM   `n_custom`
        WHERE  `n_custom`.`custom_type_id` = `n_contacts`.`id` AND `n_custom`.`custom_type` = 'contacts'
        AND `n_custom`.`gender` NOT LIKE '%male%'
    )
GROUP BY
    `n_companies`.`id`
ORDER BY
    `n_companies`.`company_name` ASC

我正在寻找上述查询,只返回Company A,因为它的两个联系人都是男性。 Company B有1名男性,1名女性。

注意:

  • n_companiesc_contacts是默认创建的表格 标准领域。 n_custom是用户可以创建自己的地方 用于存储与公司相关的各种表格的信息的字段。
  • 我无法在JOIN中进行此搜索,因为可能会有另一个ORn_contacts上搜索独立于上述查询的内容。

任何人都可以帮我解释为什么我的查询无效吗?

提前谢谢。

修改的 我刚刚意识到我的"没有"记录也不起作用。在我看来,这应该返回零行,但它并不是:

SELECT 
    `n_companies`.`id`,
    `n_companies`.`company_name`
FROM `n_companies`
LEFT JOIN `n_contacts`
    ON ( `n_contacts`.`company_id` = `n_companies`.`id` )
LEFT JOIN `n_custom` AS `custom_contacts`
    ON ( `n_contacts`.`id` = `custom_contacts`.`custom_type_id`
    AND `custom_contacts`.`custom_type` = 'contacts' )
WHERE  
    NOT EXISTS (
        SELECT `id`
        FROM   `n_custom`
        WHERE  `n_custom`.`custom_type_id` = `n_contacts`.`id` AND `n_custom`.`custom_type` = 'contacts'
        AND `n_custom`.`fav_colour` NOT LIKE '%red%'
    )
GROUP BY
    `n_companies`.`id`
ORDER BY
    `n_companies`.`company_name` ASC

2 个答案:

答案 0 :(得分:2)

你的查询似乎很复杂。怎么样:

SELECT c.id, c.company_name
FROM n_companies c LEFT JOIN
     n_contacts co
     ON  co.company_id = c.id LEFT JOIN
     n_custom cu
     ON co.id = cu.custom_type_id AND
        cu.custom_type = 'contacts'
GROUP BY c.id, c.company_name
HAVING MIN(cu.gender) = 'male' AND MIN(cu.gender) = MAX(cu.gender);

答案 1 :(得分:2)

您正在寻找其联系人符合特定条件的公司。汇总每个公司的标准,并查看HAVING子句中的结果。一个例子:

select *
from companies
where id in
(
  select company_id
  from n_contacts con
  join n_custom cus on cus.custom_type_id = con.id and cus.custom_type = 'contacts'
  group by company_id
  having sum(cus.gender = 'male') = count(*) -- all contacts are male
     and sum(cus.fav_colour = 'red') = 2 -- at least two contacts like red
     and sum(cus.fav_colour = 'green') = 0 -- no contact likes green
     and sum(con.contact_name = 'John') > 0 -- at least one contact is named John
);