开发者

help writing sql query

I have a database that looks like:

contacts

id | name
1  | bob
2  | jack
3  | jill

contactsGroupLink

cId| gId
1  | 1
2  | 3
2  | 3
2  | 5
3  | 4

So basically,

a contact is linked to a group by an entry in the contactsGroupLink table.

A contact may be in multiple groups, but a contact may only be on a group once.

The query I want to write is

select `name` 
  from contacts 
 where contact.id not in (select contactId 
                           from contactsGroupLink 
                          where groupId = 5);

Which works. It returns bob and jill.

however its not very optimized as it has a dep开发者_如何转开发endent sub-query. can anyone help optimize it?


Because both columns are unlikely to be NULL, in MySQL (only) the best option is to use the LEFT JOIN/IS NULL:

   SELECT c.name
     FROM CONTACTS c
LEFT JOIN CONTACTSGROUPLINK cgl ON cgl.contactid = c.id
                               AND cgl.groupid = 5
    WHERE cgl.contactid IS NULL

If the columns were nullable, NOT EXISTS is a better choice:

   SELECT c.name
     FROM CONTACTS c
    WHERE NOT EXISTS (SELECT NULL
                        FROM CONTACTSGROUPLINK cgl
                       WHERE cgl.contactid = c.id
                         AND cgl.groupid = 5)

The two columns in the CONTACTSGROUPLINK table should be the primary key, which will automatically index the columns (as of ~5.0+?). Otherwise, make sure the columns are indexed.


...

where not exists (
  select 1 from contactsGroupLink cgl
  where cgl.contactid = contact.id and cgl.groupid = 5
)

This should efficiently use the index by contactsGroupLink(contactid, groupid) you already have.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜