MySQL复杂的联系人表

时间:2012-04-12 07:22:10

标签: mysql subquery left-join coalesce

我正在尝试输出联系人姓名列表及其给定公司的电话号码和电子邮件地址。

我面临的问题是让它根据以下标准输出联系人:

联系人可能有也可能没有姓名,电子邮件或电话,但他们必须至少有一个出现在结果中。

每家公司可以有多个联系人。

每个联系人可以有多个电子邮件地址和/或电话号码。

联系人上有一个主要标志,因此如果有多个联系人且其中一个是主要联系人,则应该选择一个而不是其他非主要联系人。

我尝试了以下方法来获取联系人姓名,但没有成功:

SELECT entity_details.name,
COALESCE(
  (SELECT entity_contacts.name FROM entity_contacts
  WHERE entity_contacts.entityRef = entity_details.id
  ORDER BY entity_contacts.isPrimary = 1),
  (SELECT entity_contacts.name FROM entity_contacts
  WHERE entity_contacts.entityRef = entity_details.id)
)
AS contact
FROM entity_details
WHERE entity_details.ownerRef = ?

这是我能得到的最接近的东西,但我不确定它是否正确,并且它不优先考虑主要联系人,它只是选择entityRef上的任何和组来删除重复项:

SELECT
entity_details.name, entity_contacts.name AS contact,
entity_contacts_telephones.tel, entity_contacts_emails.email

FROM entity_details
 LEFT JOIN entity_contacts ON entity_details.id = entity_contacts.entityRef
 LEFT JOIN entity_contacts_telephones ON entity_contacts.id = entity_contacts_telephones.contactRef
 LEFT JOIN entity_contacts_emails ON entity_contacts.id = entity_contacts_emails.contactRef

WHERE entity_details.ownerRef = ?

GROUP BY entity_contacts.entityRef
LIMIT ?, ?

所有表格都是Innobd,我正在使用的是上面的编辑。所有参考文献都有关于哪里有索引的索引。

在entity_details中,大约有13000行,entity_contacts中有12000行,entity_contacts_telephones和entity_contacts_emails中有几千行。

我认为以下内容可行,但事实并非如此:

LEFT JOIN entity_contacts_telephones
  ON entity_contacts.id = entity_contacts_telephones.contactRef
  AND COALESCE(entity_contacts_telephones.isPrimary = 1, 0)

1 个答案:

答案 0 :(得分:0)

这可能有效(不确定主要是因为不清楚每个表中每个实体有多少行):

SELECT 
    entity_details.name,
    ( SELECT entity_contacts.name 
      FROM entity_contacts
      WHERE entity_contacts.entityRef = entity_details.id
      ORDER BY entity_contacts.isPrimary DESC
      LIMIT 1
    ) AS contact
FROM entity_details
WHERE entity_details.ownerRef = ?

您可能需要加入 - [greatest-n-per-group]类型:

SELECT 
    d.name,
    ...
    c.whatever
    ...
FROM 
    entity_details AS d
  JOIN
    entity_contacts AS c
      ON  c.PK =                    --- the PRIMARY KEY of contacts table
          ( SELECT cc.PK
            FROM entity_contacts AS cc
            WHERE cc.entityRef = d.id
            ORDER BY cc.isPrimary DESC
            LIMIT 1
           ) 
WHERE d.ownerRef = ?

(entityRef, isPrimary)上的索引有助于提高绩效。