Mysql 转弯抹角
Mysql get where not in with a twist
我想获取没有联系方式的公司 main_phone 或 phone 这是我的架构
Firms table
+----+-------+
| id | name |
+----+-------+
| 1 | Firm1 |
| 2 | Firm2 |
| 3 | Firm3 |
+----+-------+
Contacts
+----+----------+---------+
| id | label | firm_id |
+----+----------+---------+
| 1 | Contact1 | 1 |
| 2 | Contact2 | 1 |
| 3 | Contact3 | 2 |
| 4 | Contact4 | 3 |
+----+----------+---------+
contact_methods
+----+-------------+------------+
| id | method_type | contact_id |
+----+-------------+------------+
| 1 | main_phone | 1 |
| 2 | main_fax | 1 |
| 3 | email | 1 |
| 4 | main_fax | 4 |
| 5 | main_fax | 3 |
| 6 | phone | 2 |
| 7 | main_mobile | 1 |
| 8 | url | 4 |
+----+-------------+------------+
这是我的查询
SELECT
firms.id
FROM firms
JOIN contacts ON (contactable_id = firms.id)
JOIN contact_methods ON contacts.id = contact_methods.contact_id
WHERE
firms.active = 1
AND
contact_methods.method_type NOT IN ('mobile','phone','main_mobile','main_phone')
我正在获取所有公司 :s
您的代码检查每个公司是否有 any 不属于列表的联系人类型 - 而您要确保 none 的公司联系人确实如此。
一个选项使用聚合:
select f.*
from firm f
left join contacts c on c.firm_id = f.id
left join contact_methods cm on cm.contact_id = c.id
group by f.id
having not max(cm.method_type in ('mobile','phone','main_mobile','main_phone')) <=> 1
或者,您可以使用 not exists
:
select f.*
from firm f
where not exists (
select 1
from contacts c
inner join contact_methods cm on cm.contact_id = c.id
where c.firm_id = f.id and cm.method_type in ('mobile','phone','main_mobile','main_phone')
)
SELECT *
FROM firms
WHERE NOT EXIST ( SELECT NULL
FROM contacts
WHERE firms.id = contacts.firm_id )
contact_methods
此任务不需要。
如果您需要相同的联系人类型,请使用:
SELECT *
FROM firms
WHERE NOT EXIST ( SELECT NULL
FROM contacts
JOIN contact_methods ON contacts.id = contact_methods.contact_id
WHERE firms.id = contacts.firm_id
AND contact_methods.method_type NOT IN ({types list}) )
i want just the firms.id that does not have a contact method in ('mobile','phone','main_mobile','main_phone')
SELECT *
FROM firms
WHERE NOT EXIST ( SELECT NULL
FROM contacts
JOIN contact_methods ON contacts.id = contact_methods.contact_id
WHERE firms.id = contacts.firm_id
AND contact_methods.method_type IN ('mobile', 'phone', 'main_mobile', 'main_phone') )
我想获取没有联系方式的公司 main_phone 或 phone 这是我的架构
Firms table +----+-------+ | id | name | +----+-------+ | 1 | Firm1 | | 2 | Firm2 | | 3 | Firm3 | +----+-------+ Contacts +----+----------+---------+ | id | label | firm_id | +----+----------+---------+ | 1 | Contact1 | 1 | | 2 | Contact2 | 1 | | 3 | Contact3 | 2 | | 4 | Contact4 | 3 | +----+----------+---------+ contact_methods +----+-------------+------------+ | id | method_type | contact_id | +----+-------------+------------+ | 1 | main_phone | 1 | | 2 | main_fax | 1 | | 3 | email | 1 | | 4 | main_fax | 4 | | 5 | main_fax | 3 | | 6 | phone | 2 | | 7 | main_mobile | 1 | | 8 | url | 4 | +----+-------------+------------+
这是我的查询
SELECT firms.id FROM firms JOIN contacts ON (contactable_id = firms.id) JOIN contact_methods ON contacts.id = contact_methods.contact_id WHERE firms.active = 1 AND contact_methods.method_type NOT IN ('mobile','phone','main_mobile','main_phone')
我正在获取所有公司 :s
您的代码检查每个公司是否有 any 不属于列表的联系人类型 - 而您要确保 none 的公司联系人确实如此。
一个选项使用聚合:
select f.*
from firm f
left join contacts c on c.firm_id = f.id
left join contact_methods cm on cm.contact_id = c.id
group by f.id
having not max(cm.method_type in ('mobile','phone','main_mobile','main_phone')) <=> 1
或者,您可以使用 not exists
:
select f.*
from firm f
where not exists (
select 1
from contacts c
inner join contact_methods cm on cm.contact_id = c.id
where c.firm_id = f.id and cm.method_type in ('mobile','phone','main_mobile','main_phone')
)
SELECT *
FROM firms
WHERE NOT EXIST ( SELECT NULL
FROM contacts
WHERE firms.id = contacts.firm_id )
contact_methods
此任务不需要。
如果您需要相同的联系人类型,请使用:
SELECT *
FROM firms
WHERE NOT EXIST ( SELECT NULL
FROM contacts
JOIN contact_methods ON contacts.id = contact_methods.contact_id
WHERE firms.id = contacts.firm_id
AND contact_methods.method_type NOT IN ({types list}) )
i want just the firms.id that does not have a contact method in ('mobile','phone','main_mobile','main_phone')
SELECT *
FROM firms
WHERE NOT EXIST ( SELECT NULL
FROM contacts
JOIN contact_methods ON contacts.id = contact_methods.contact_id
WHERE firms.id = contacts.firm_id
AND contact_methods.method_type IN ('mobile', 'phone', 'main_mobile', 'main_phone') )