次の3つのテーブルがあります:Contact、Custom_Field、Custom_Field_Value。
各連絡先は、Custom_Fieldごとに1つのCustom_Field_Valueレコードを持つことができます。したがって、ContactとCustom_Field_Valueの間には1:多くの関係がありますが、それほど単純ではありません。
特定のCustom_Fieldが設定されていない連絡先を選択する必要がある(つまり、ContactとCustom_Fieldにリンクする対応するCustom_Field_Valueレコードが存在しない)1つのエッジケースを除いて、すべてが正常に機能します。これは驚くほど難しいです。通常の「左結合してNULLを探す」アプローチを使用することはできません。これは、カスタムフィールドが異なる可能性があるためですが、探しているものではありません。「WhereCustom_Field_ID=10」と言う必要がありますが、探しているものが存在しないため、言えません。
私の考え方はこの方向に向かっていましたが、今は結び目で結ばれています。
Select ID, First_Name, Last_Name, CF_ID From
(
(Select Contact.ID, First_Name, Last_Name, Custom_Field_Value.ID as CFV_ID, Custom_Field_Value.CustomFieldID as CF_ID, TextValue
From Contact Inner Join Custom_Field_Value on Contact.ID = Custom_Field_Value.ContactID
Where Custom_Field_Value.CustomFieldID=23 Order By Contact.ID)
UNION
(Select Contact.ID, First_Name, Last_Name, Custom_Field_Value.ID as CFV_ID, Custom_Field_Value.CustomFieldID as CF_ID, TextValue
From Contact LEFT Join Custom_Field_Value on Contact.ID = Custom_Field_Value.ContactID
Order by Contact.ID)
) as A
Group BY `ID`, CF_ID ASC
何百万ものレコードが存在する可能性があり、誰かがカスタムフィールドを追加するたびに、データベースは何百万もの対応する空白のレコードを挿入する必要があるため、すべての可能性に対して空白のレコードを作成したくありません。
私たちがこれを行うことができれば本当に素晴らしいでしょう:
Select ID From thingy
EXCLUDE
Select * From thingy Where x = true
これは厄介なものですが、それを気に入る人がそこにいることを私は知っています:)