0

特定の会社の連絡先名と電話番号および電子メールアドレスのリストを出力しようとしています。

私が直面している問題は、次の基準に基づいて連絡先を出力することです。

連絡先には、名前、電子メール、または電話がある場合とない場合がありますが、結果に表示するには、これらの少なくとも1つが必要です。

会社ごとに複数の連絡先が存在する可能性があります。

連絡先ごとに複数のメールアドレスや電話番号が存在する可能性があります。

連絡先にはプライマリフラグがあるため、複数の連絡先があり、そのうちの1つがプライマリである場合は、他の非プライマリの代わりにその1つを選択する必要があります。

連絡先の名前を取得するために次のことを試しましたが、成功しませんでした。

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)
4

1 に答える 1

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)向上に役立ちます。

于 2012-04-12T07:26:40.610 に答える